import "@home-assistant/webawesome/dist/components/divider/divider";
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import "../../components/ha-dropdown-item";
import "../../components/ha-icon";
import "../../components/ha-select";
import type { HaSelectSelectEvent } from "../../components/ha-select";
import "../../components/ha-settings-row";
import "../../components/ha-spinner";
import "../../components/ha-svg-icon";
import { saveFrontendUserData } from "../../data/frontend";
import type { LovelaceDashboard } from "../../data/lovelace/dashboard";
import { fetchDashboards } from "../../data/lovelace/dashboard";
import { getPanelIcon, getPanelTitle } from "../../data/panel";
import type { HomeAssistant, PanelInfo } from "../../types";
import { PANEL_DASHBOARDS } from "../config/lovelace/dashboards/ha-config-lovelace-dashboards";

const USE_SYSTEM_VALUE = "___use_system___";

@customElement("ha-pick-dashboard-row")
class HaPickDashboardRow extends LitElement {
  @property({ attribute: false }) public hass!: HomeAssistant;

  @property({ type: Boolean }) public narrow = false;

  @state() private _dashboards?: LovelaceDashboard[];

  protected firstUpdated(changedProps: PropertyValues<this>) {
    super.firstUpdated(changedProps);
    this._getDashboards();
  }

  protected render(): TemplateResult {
    const value = this.hass.userData?.default_panel || USE_SYSTEM_VALUE;
    return html`
      <ha-settings-row .narrow=${this.narrow}>
        <span slot="heading">
          ${this.hass.localize("ui.panel.profile.dashboard.header")}
        </span>
        <span slot="description">
          ${this.hass.localize("ui.panel.profile.dashboard.description")}
        </span>
        ${
          this._dashboards
            ? html`
                <ha-select
                  .label=${this.hass.localize(
                    "ui.panel.profile.dashboard.dropdown_label"
                  )}
                  .value=${this._valueLabel(value)}
                  @selected=${this._dashboardChanged}
                >
                  <ha-dropdown-item
                    .value=${USE_SYSTEM_VALUE}
                    .selected=${value === USE_SYSTEM_VALUE}
                  >
                    ${this.hass.localize("ui.panel.profile.dashboard.system")}
                  </ha-dropdown-item>
                  <wa-divider></wa-divider>
                  ${PANEL_DASHBOARDS.map((panel) => {
                    const panelInfo = this.hass.panels[panel] as
                      PanelInfo | undefined;
                    if (!panelInfo) {
                      return nothing;
                    }
                    return html`
                      <ha-dropdown-item
                        value=${panelInfo.url_path}
                        .selected=${value === panelInfo.url_path}
                      >
                        <ha-icon
                          slot="icon"
                          .icon=${getPanelIcon(panelInfo)}
                        ></ha-icon>
                        ${getPanelTitle(this.hass, panelInfo)}
                      </ha-dropdown-item>
                    `;
                  })}
                  ${
                    this._dashboards.length
                      ? html`
                          <wa-divider></wa-divider>
                          ${this._dashboards.map((dashboard) => {
                            if (
                              !this.hass.user!.is_admin &&
                              dashboard.require_admin
                            ) {
                              return "";
                            }
                            return html`
                              <ha-dropdown-item
                                .value=${dashboard.url_path}
                                .selected=${value === dashboard.url_path}
                              >
                                <ha-icon
                                  slot="icon"
                                  .icon=${dashboard.icon || "mdi:view-dashboard"}
                                ></ha-icon>
                                ${dashboard.title}
                              </ha-dropdown-item>
                            `;
                          })}
                        `
                      : nothing
                  }
                </ha-select>
              `
            : html`<div class="loading">
                <ha-spinner size="small"></ha-spinner>
              </div>`
        }
      </ha-settings-row>
    `;
  }

  private async _getDashboards() {
    this._dashboards = await fetchDashboards(this.hass);
  }

  private _dashboardChanged(ev: HaSelectSelectEvent): void {
    const value = ev.detail.value;
    if (!value) {
      return;
    }
    const urlPath = value === USE_SYSTEM_VALUE ? undefined : value;
    if (urlPath === this.hass.userData?.default_panel) {
      return;
    }
    saveFrontendUserData(this.hass.connection, "core", {
      ...this.hass.userData,
      default_panel: urlPath,
    });
  }

  private _valueLabel = memoizeOne((value: string) => {
    if (value === USE_SYSTEM_VALUE) {
      return this.hass.localize("ui.panel.profile.dashboard.system");
    }
    if (value === "lovelace") {
      return this.hass.localize("ui.panel.profile.dashboard.lovelace");
    }
    const panelInfo = this.hass.panels[value] as PanelInfo | undefined;
    if (panelInfo) {
      return getPanelTitle(this.hass, panelInfo);
    }
    const dashboard = this._dashboards?.find((dash) => dash.url_path === value);
    if (dashboard) {
      return dashboard.title;
    }
    return value;
  });

  static get styles(): CSSResultGroup {
    return [
      css`
        .loading {
          display: flex;
          justify-content: center;
          align-items: center;
          height: 56px;
          width: 200px;
        }

        ha-select {
          display: block;
          width: 100%;
        }
      `,
    ];
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "ha-pick-dashboard-row": HaPickDashboardRow;
  }
}
