import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { relativeTime } from "../../../common/datetime/relative_time";
import { fireEvent } from "../../../common/dom/fire_event";
import "../../../components/ha-button";
import "../../../components/ha-dialog-footer";
import "../../../components/ha-dialog";
import "../../../components/ha-md-list";
import "../../../components/ha-md-list-item";
import type { HaSwitch } from "../../../components/ha-switch";
import "../../../components/ha-switch";
import type { BackupConfig } from "../../../data/backup";
import { fetchBackupConfig } from "../../../data/backup";
import { getSupervisorUpdateConfig } from "../../../data/supervisor/update";
import type { HassDialog } from "../../../dialogs/make-dialog-manager";
import type { HomeAssistant } from "../../../types";
import type { LabsPreviewFeatureEnableDialogParams } from "./show-dialog-labs-preview-feature-enable";

@customElement("dialog-labs-preview-feature-enable")
export class DialogLabsPreviewFeatureEnable
  extends LitElement
  implements HassDialog<LabsPreviewFeatureEnableDialogParams>
{
  @property({ attribute: false }) public hass!: HomeAssistant;

  @state() private _params?: LabsPreviewFeatureEnableDialogParams;

  @state() private _backupConfig?: BackupConfig;

  @state() private _createBackup = false;

  @state() private _open = false;

  public async showDialog(
    params: LabsPreviewFeatureEnableDialogParams
  ): Promise<void> {
    this._params = params;
    this._createBackup = false;
    this._open = true;
    this._fetchBackupConfig();
    if (isComponentLoaded(this.hass.config, "hassio")) {
      this._fetchUpdateBackupConfig();
    }
  }

  public closeDialog(): boolean {
    this._open = false;
    return true;
  }

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

  private async _fetchBackupConfig() {
    try {
      const { config } = await fetchBackupConfig(this.hass);
      this._backupConfig = config;
    } catch (err) {
      // Ignore error, user will get manual backup option
      // eslint-disable-next-line no-console
      console.error(err);
    }
  }

  private async _fetchUpdateBackupConfig() {
    try {
      const config = await getSupervisorUpdateConfig(this.hass);
      this._createBackup = config.core_backup_before_update;
    } catch (err) {
      // Ignore error, user can still toggle the switch manually
      // eslint-disable-next-line no-console
      console.error(err);
    }
  }

  private _computeCreateBackupTexts():
    | { title: string; description?: string }
    | undefined {
    if (
      !this._backupConfig ||
      !this._backupConfig.automatic_backups_configured ||
      !this._backupConfig.create_backup.password ||
      this._backupConfig.create_backup.agent_ids.length === 0
    ) {
      return {
        title: this.hass.localize("ui.panel.config.labs.create_backup.manual"),
        description: this.hass.localize(
          "ui.panel.config.labs.create_backup.manual_description"
        ),
      };
    }

    const lastAutomaticBackupDate = this._backupConfig
      .last_completed_automatic_backup
      ? new Date(this._backupConfig.last_completed_automatic_backup)
      : null;
    const now = new Date();

    return {
      title: this.hass.localize("ui.panel.config.labs.create_backup.automatic"),
      description: lastAutomaticBackupDate
        ? this.hass.localize(
            "ui.panel.config.labs.create_backup.automatic_description_last",
            {
              relative_time: relativeTime(
                lastAutomaticBackupDate,
                this.hass.locale,
                now,
                true
              ),
            }
          )
        : this.hass.localize(
            "ui.panel.config.labs.create_backup.automatic_description_none"
          ),
    };
  }

  private _createBackupChanged(ev: Event): void {
    this._createBackup = (ev.target as HaSwitch).checked;
  }

  private _handleCancel(): void {
    this.closeDialog();
  }

  private _handleConfirm(): void {
    if (this._params) {
      this._params.onConfirm(this._createBackup);
    }
    this.closeDialog();
  }

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

    const createBackupTexts = this._computeCreateBackupTexts();

    return html`
      <ha-dialog
        .open=${this._open}
        header-title=${this.hass.localize("ui.panel.config.labs.enable_title")}
        @closed=${this._dialogClosed}
      >
        <p>
          ${this.hass.localize(
            `component.${this._params.preview_feature.domain}.preview_features.${this._params.preview_feature.preview_feature}.enable_confirmation`
          ) || this.hass.localize("ui.panel.config.labs.enable_confirmation")}
        </p>
        ${createBackupTexts
          ? html`
              <ha-md-list>
                <ha-md-list-item>
                  <span slot="headline">${createBackupTexts.title}</span>
                  ${createBackupTexts.description
                    ? html`
                        <span slot="supporting-text">
                          ${createBackupTexts.description}
                        </span>
                      `
                    : nothing}
                  <ha-switch
                    slot="end"
                    .checked=${this._createBackup}
                    @change=${this._createBackupChanged}
                  ></ha-switch>
                </ha-md-list-item>
              </ha-md-list>
            `
          : nothing}
        <ha-dialog-footer slot="footer">
          <ha-button
            slot="secondaryAction"
            appearance="plain"
            @click=${this._handleCancel}
          >
            ${this.hass.localize("ui.common.cancel")}
          </ha-button>
          <ha-button
            slot="primaryAction"
            appearance="filled"
            variant="brand"
            @click=${this._handleConfirm}
          >
            ${this.hass.localize("ui.panel.config.labs.enable")}
          </ha-button>
        </ha-dialog-footer>
      </ha-dialog>
    `;
  }

  static readonly styles = css`
    ha-dialog {
      --dialog-content-padding: 0;
    }

    p {
      margin: 0 var(--ha-space-6) var(--ha-space-6);
      color: var(--secondary-text-color);
    }

    ha-md-list {
      background: none;
      --md-list-item-leading-space: var(--ha-space-6);
      --md-list-item-trailing-space: var(--ha-space-6);
      margin: 0;
      padding: 0;
      border-top: var(--ha-border-width-sm) solid var(--divider-color);
    }
  `;
}

declare global {
  interface HTMLElementTagNameMap {
    "dialog-labs-preview-feature-enable": DialogLabsPreviewFeatureEnable;
  }
}
