import { LitElement, type PropertyValues, css, html } from 'lit';
import { customElement, property, query, state } from 'lit/decorators.js';
import { when } from 'lit/directives/when.js';

export class ArxInputChangeEvent extends CustomEvent<{ value: string }> {
  constructor(value: string) {
    super('change', { detail: { value } });
  }
}

@customElement('arx-input')
export class StyledInput extends LitElement {
  @property() placeholder = '';
  @property() value = '';
  @property({ type: Boolean }) disabled = false;
  @property() type: 'text' | 'number' | 'password' | 'date' | 'time' = 'text';
  @property() name = '';
  @property({ type: Boolean }) required = false;
  @property() label = '';
  @state() override lang = 'en-US';

  @query('input') private _input!: HTMLInputElement;

  @state() private _value = '';

  override connectedCallback(): void {
    super.connectedCallback();
    const dateTimeFormatOptions = JSON.parse(localStorage.getItem('dateTimeFormatOptions') || '{}');
    if (dateTimeFormatOptions?.locale) this.lang = dateTimeFormatOptions.locale;
  }

  protected override firstUpdated(_changedProperties: PropertyValues): void {
    this._value = this.value;
  }

  protected override updated(changedProperties: PropertyValues): void {
    if (changedProperties.has('value')) this._value = this.value;
  }

  static override styles = css`
    :host {
      display: inline-block;
      width: 100%;
      margin-bottom: 8px;
    }

    label {
      display: block;
      margin-bottom: 8px;
      font-size: 14px;
      color: var(--color-base-content);
      font-weight: 500;
    }

    input {
      width: 100%;
      padding: 14px 16px;
      font-size: 16px;
      color: var(--color-base-content);
      background: var(--color-base-100);
      border: var(--border) solid var(--color-base-300);
      border-radius: var(--radius-field);
      box-shadow: inset calc(var(--depth) * 2px) calc(var(--depth) * 2px)
          calc(var(--depth) * 4px)
          oklch(from var(--color-base-content) l c h / 0.15),
        inset calc(var(--depth) * -2px) calc(var(--depth) * -2px)
          calc(var(--depth) * 4px) oklch(from var(--color-base-100) l c h / 0.7),
        0 0 0 transparent;
      transition: all 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
    }

    input::placeholder {
      color: var(--color-secondary);
      transition: all 0.3s cubic-bezier(0.25, 0.1, 0.25, 1.1);
    }

    input:hover {
      transform: translateY(-1px);
      background: oklch(from var(--color-base-100) calc(l + 0.02) c h);
    }

    input:hover::placeholder {
      transform: translateX(3px);
    }

    input:focus {
      outline: none;
      transform: translateY(1px);
      border-top: var(--border) solid
        oklch(from var(--color-base-300) l c h / 0.8);
      border-left: var(--border) solid
        oklch(from var(--color-base-300) l c h / 0.8);
      border-bottom: var(--border) solid
        oklch(from var(--color-base-200) l c h / 0.8);
      border-right: var(--border) solid
        oklch(from var(--color-base-200) l c h / 0.8);
      box-shadow: inset calc(var(--depth) * 3px) calc(var(--depth) * 3px)
          calc(var(--depth) * 5px)
          oklch(from var(--color-base-content) l c h / 0.2),
        inset calc(var(--depth) * -1px) calc(var(--depth) * -1px)
          calc(var(--depth) * 3px) oklch(from var(--color-base-100) l c h / 0.5),
        0 0 0 transparent;
      background: linear-gradient(
        145deg,
        oklch(from var(--color-base-100) calc(l - 0.03) c h),
        oklch(from var(--color-base-100) l c h)
      );
    }

    input:disabled {
      opacity: 0.7;
      cursor: not-allowed;
      box-shadow: inset calc(var(--depth) * 1px) calc(var(--depth) * 1px)
          calc(var(--depth) * 2px)
          oklch(from var(--color-base-content) l c h / 0.05),
        inset calc(var(--depth) * -1px) calc(var(--depth) * -1px)
          calc(var(--depth) * 2px) oklch(from var(--color-base-100) l c h / 0.4);
      transform: none;
    }
  `;

  override render() {
    return html`
      ${when(this.label, () => html`<label for="input-${this.name}">${this.label}</label>`)}
      <input
        .value=${this._value}
        ?disabled=${this.disabled}
        ?required=${this.required}
        placeholder=${this.placeholder}
        type=${this.type}
        name=${this.name}
        lang=${this.lang}
        @input=${this._handleInput}
        @focus=${this._handleFocus}
        @blur=${this._handleBlur}
        @keydown=${this._handleKeyDown}
        @keyup=${this._handleKeyUp}
      />
    `;
  }

  private _handleKeyDown(e: KeyboardEvent) {
    this.dispatchEvent(new CustomEvent('keydown', { detail: { key: e.key }, composed: true, bubbles: true }));
  }

  private _handleKeyUp(e: KeyboardEvent) {
    this.dispatchEvent(new CustomEvent('keyup', { detail: { key: e.key }, composed: true, bubbles: true }));
  }

  private _handleFocus() {
    this.dispatchEvent(new CustomEvent('focus', { composed: true, bubbles: true }));
  }

  private _handleBlur() {
    this.dispatchEvent(new CustomEvent('blur', { composed: true, bubbles: true }));
  }

  private _handleInput(e: InputEvent) {
    this._value = this._input.value;
    this.dispatchEvent(new ArxInputChangeEvent(this._value));
    e.preventDefault();
  }
}
