import { consume } from "@lit/context";
import { css, html, LitElement } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import { transform } from "../../common/decorators/transform";
import type { DateTimeSelector } from "../../data/selector";
import { internationalizationContext } from "../../data/context";
import type { FrontendLocaleData } from "../../data/translation";
import type { HomeAssistantInternationalization } from "../../types";
import "../ha-date-input";
import type { HaDateInput } from "../ha-date-input";
import "../ha-time-input";
import "../ha-input-helper-text";
import type { HaTimeInput } from "../ha-time-input";

@customElement("ha-selector-datetime")
export class HaDateTimeSelector extends LitElement {
  @state()
  @consume({ context: internationalizationContext, subscribe: true })
  @transform<HomeAssistantInternationalization, FrontendLocaleData>({
    transformer: ({ locale }) => locale,
  })
  private _locale!: FrontendLocaleData;

  @property({ attribute: false }) public selector!: DateTimeSelector;

  @property() public value?: string;

  @property() public label?: string;

  @property() public helper?: string;

  @property({ type: Boolean, reflect: true }) public disabled = false;

  @property({ type: Boolean }) public required = true;

  @query("ha-date-input") private _dateInput!: HaDateInput;

  @query("ha-time-input") private _timeInput!: HaTimeInput;

  public reportValidity(): boolean {
    return this._dateInput.reportValidity() && this._timeInput.reportValidity();
  }

  protected render() {
    const values =
      typeof this.value === "string" ? this.value.split(" ") : undefined;

    return html`
      <div class="input">
        <ha-date-input
          .label=${this.label}
          .locale=${this._locale}
          .disabled=${this.disabled}
          .required=${this.required}
          .value=${values?.[0]}
          @value-changed=${this._valueChanged}
        >
        </ha-date-input>
        <ha-time-input
          enable-second
          .value=${values?.[1] || "00:00:00"}
          .locale=${this._locale}
          .disabled=${this.disabled}
          .required=${this.required}
          @value-changed=${this._valueChanged}
        ></ha-time-input>
      </div>
      ${this.helper
        ? html`<ha-input-helper-text .disabled=${this.disabled}
            >${this.helper}</ha-input-helper-text
          >`
        : ""}
    `;
  }

  private _valueChanged(ev: CustomEvent): void {
    ev.stopPropagation();
    if (this._dateInput.value && this._timeInput.value) {
      fireEvent(this, "value-changed", {
        value: `${this._dateInput.value} ${this._timeInput.value}`,
      });
    }
  }

  static styles = css`
    .input {
      display: flex;
      /* Align the input fields by their top edge so the date field's underline
         lines up with the time field, since ha-date-input reserves extra space
         below for its hint while ha-time-input does not. */
      align-items: flex-start;
      flex-direction: row;
    }

    ha-date-input {
      min-width: 150px;
      margin-right: 4px;
      margin-inline-end: 4px;
      margin-inline-start: initial;
    }
  `;
}

declare global {
  interface HTMLElementTagNameMap {
    "ha-selector-datetime": HaDateTimeSelector;
  }
}
