import type { CSSResultGroup } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-alert";
import "../../../../components/ha-button";
import "../../../../components/ha-icon";
import "../../../../components/ha-dialog-footer";
import "../../../../components/ha-list";
import "../../../../components/ha-radio-list-item";
import "../../../../components/ha-select";
import "../../../../components/ha-dialog";
import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
import { fetchConfig } from "../../../../data/lovelace/config/types";
import { isStrategyView } from "../../../../data/lovelace/config/view";
import type { LovelaceDashboard } from "../../../../data/lovelace/dashboard";
import { fetchDashboards } from "../../../../data/lovelace/dashboard";
import { getDefaultPanelUrlPath } from "../../../../data/panel";
import { haStyleDialog } from "../../../../resources/styles";
import type { HomeAssistant, ValueChangedEvent } from "../../../../types";
import type { SelectViewDialogParams } from "./show-select-view-dialog";

declare global {
  interface HASSDomEvents {
    "view-selected": {
      view: number;
    };
  }
}

@customElement("hui-dialog-select-view")
export class HuiDialogSelectView extends LitElement {
  public hass!: HomeAssistant;

  @state() private _params?: SelectViewDialogParams;

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

  @state() private _urlPath?: string | null;

  @state() private _config?: LovelaceConfig;

  @state() private _selectedViewIdx = 0;

  @state() private _open = false;

  public showDialog(params: SelectViewDialogParams): void {
    this._config = params.lovelaceConfig;
    this._urlPath = params.urlPath;
    this._params = params;
    this._open = true;
    if (this._params.allowDashboardChange) {
      this._getDashboards();
    }
  }

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

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

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

    const defaultPanel = getDefaultPanelUrlPath(this.hass);

    return html`
      <ha-dialog
        .open=${this._open}
        header-title=${this._params.header ||
        this.hass.localize("ui.panel.lovelace.editor.select_view.header")}
        @closed=${this._dialogClosed}
      >
        ${this._params.allowDashboardChange
          ? html`<ha-select
              .label=${this.hass.localize(
                "ui.panel.lovelace.editor.select_view.dashboard_label"
              )}
              .disabled=${!this._dashboards.length}
              .value=${this._urlPath || defaultPanel}
              @selected=${this._dashboardChanged}
              autofocus
              .options=${this._dashboards
                .map((dashboard) => ({
                  value: dashboard.url_path,
                  label: `${dashboard.title}${dashboard.id === "lovelace" ? ` (${this.hass.localize("ui.common.default")})` : ""}`,
                  disabled: dashboard.mode !== "storage",
                }))
                .sort((a, b) =>
                  a.value === "lovelace"
                    ? -1
                    : b.value === "lovelace"
                      ? 1
                      : a.label.localeCompare(b.label)
                )}
            >
            </ha-select>`
          : nothing}
        ${!this._config || (this._config.views || []).length < 1
          ? html`<ha-alert alert-type="error"
              >${this.hass.localize(
                this._config
                  ? "ui.panel.lovelace.editor.select_view.no_views"
                  : "ui.panel.lovelace.editor.select_view.no_config"
              )}</ha-alert
            >`
          : this._config.views.length > 1
            ? html`
                <ha-list>
                  ${this._config.views.map((view, idx) => {
                    const isStrategy = isStrategyView(view);

                    return html`
                      <ha-radio-list-item
                        .graphic=${this._config?.views.some(({ icon }) => icon)
                          ? "icon"
                          : nothing}
                        @click=${this._viewChanged}
                        .value=${idx.toString()}
                        .selected=${this._selectedViewIdx === idx}
                        .disabled=${isStrategy &&
                        !this._params?.includeStrategyViews}
                        ?autofocus=${idx === 0 &&
                        !this._params!.allowDashboardChange}
                      >
                        <span>
                          ${view.title}${isStrategy
                            ? ` (${this.hass.localize("ui.panel.lovelace.editor.select_view.strategy_type")})`
                            : nothing}
                        </span>

                        <ha-icon .icon=${view.icon} slot="graphic"></ha-icon>
                      </ha-radio-list-item>
                    `;
                  })}
                </ha-list>
              `
            : nothing}
        <ha-dialog-footer slot="footer">
          <ha-button
            slot="secondaryAction"
            @click=${this.closeDialog}
            appearance="plain"
          >
            ${this.hass!.localize("ui.common.cancel")}
          </ha-button>
          <ha-button
            slot="primaryAction"
            .disabled=${!this._config || (this._config.views || []).length < 1}
            @click=${this._selectView}
          >
            ${this._params.actionLabel || this.hass!.localize("ui.common.move")}
          </ha-button>
        </ha-dialog-footer>
      </ha-dialog>
    `;
  }

  private async _getDashboards() {
    this._dashboards =
      this._params!.dashboards || (await fetchDashboards(this.hass));
  }

  private async _dashboardChanged(ev: ValueChangedEvent<string>) {
    let urlPath: string | null = ev.detail.value;
    if (urlPath === this._urlPath) {
      return;
    }
    if (urlPath === "lovelace") {
      urlPath = null;
    }
    this._urlPath = urlPath;
    this._selectedViewIdx = 0;
    try {
      this._config = (await fetchConfig(
        this.hass.connection,
        urlPath,
        false
      )) as LovelaceConfig;
    } catch (_err: any) {
      this._config = undefined;
    }
  }

  private _viewChanged(e) {
    const view = Number(e.target.value);

    if (!isNaN(view)) {
      this._selectedViewIdx = view;
    }
  }

  private _selectView(): void {
    fireEvent(this, "view-selected", { view: this._selectedViewIdx });
    this._params!.viewSelectedCallback(
      this._urlPath!,
      this._config!,
      this._selectedViewIdx
    );
    this.closeDialog();
  }

  static get styles(): CSSResultGroup {
    return [
      haStyleDialog,
      css`
        ha-select {
          width: 100%;
        }
        mwc-radio-list-item {
          direction: ltr;
        }
      `,
    ];
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "hui-dialog-select-view": HuiDialogSelectView;
  }
}
