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

@customElement('arx-toggle')
export class StyledToggle extends LitElement {
  @property() label = '';
  @property({ type: Boolean, reflect: true }) checked = false;
  @property({ type: Boolean }) disabled = false;
  @property() name = '';
  @property({ type: Boolean }) required = false;
  @property() value = 'on';

  override connectedCallback() {
    super.connectedCallback();
    if (!this.checked) this.value = 'off';
  }

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

    .toggle-container {
      display: flex;
      align-items: center;
      gap: 12px;
    }

    label {
      font-size: 14px;
      color: var(--color-base-content);
      font-weight: 500;
      cursor: pointer;
    }

    .toggle-wrapper {
      position: relative;
      display: inline-block;
      width: 48px;
      height: 24px;
    }

    .toggle-input {
      opacity: 0;
      width: 0;
      height: 0;
      position: absolute;
    }

    .toggle-track {
      position: absolute;
      cursor: pointer;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: var(--color-base-100);
      border-radius: 24px;
      transition: all 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
      border: var(--border) solid var(--color-base-300);
      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);
    }

    .toggle-track:hover {
      background-color: oklch(from var(--color-base-100) calc(l + 0.02) c h);
    }

    .toggle-knob {
      position: absolute;
      height: 18px;
      width: 18px;
      left: 3px;
      bottom: 2px;
      background-color: var(--color-base-content);
      border-radius: 50%;
      transition: all 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
      box-shadow: calc(var(--depth) * 2px) calc(var(--depth) * 2px)
          calc(var(--depth) * 4px)
          oklch(from var(--color-base-content) l c h / 0.2),
        calc(var(--depth) * -1px) calc(var(--depth) * -1px)
          calc(var(--depth) * 3px) oklch(from var(--color-base-100) l c h / 0.3);
    }

    .toggle-input:checked + .toggle-track {
      background-color: var(--color-base-100);
      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);
    }

    .toggle-input:checked + .toggle-track .toggle-knob {
      transform: translateX(24px);
      background-color: var(--color-accent);
    }

    .toggle-input:focus + .toggle-track {
      outline: none;
      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 2px oklch(from var(--color-accent) l c h / 0.3);
    }

    .toggle-input:disabled + .toggle-track {
      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);
    }

    .toggle-input:disabled + .toggle-track .toggle-knob {
      background-color: var(--color-secondary);
      box-shadow: calc(var(--depth) * 1px) calc(var(--depth) * 1px)
          calc(var(--depth) * 2px)
          oklch(from var(--color-base-content) l c h / 0.1),
        calc(var(--depth) * -1px) calc(var(--depth) * -1px)
          calc(var(--depth) * 2px) oklch(from var(--color-base-100) l c h / 0.2);
    }
  `;

  override render() {
    return html`
      <div class="toggle-container">
        ${when(this.label, () => html` <label for="toggle-${this.name}">${this.label}</label> `)}
        <div class="toggle-wrapper">
          <input
            type="checkbox"
            id="toggle-${this.name}"
            class="toggle-input"
            .checked=${this.checked}
            ?disabled=${this.disabled}
            ?required=${this.required}
            name=${this.name}
            value=${this.value}
            @change=${this._handleChange}
            @focus=${this._handleFocus}
            @blur=${this._handleBlur}
            @keydown=${this._handleKeyDown}
          />
          <label for="toggle-${this.name}" class="toggle-track">
            <span class="toggle-knob"></span>
          </label>
        </div>
      </div>
    `;
  }

  private _handleChange(e: Event) {
    const checkbox = e.target as HTMLInputElement;
    this.checked = checkbox.checked;
    this.dispatchEvent(
      new CustomEvent('change', {
        detail: { checked: this.checked, value: this.value },
        bubbles: true,
        composed: true,
      }),
    );
  }

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

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

  private _handleKeyDown(e: KeyboardEvent) {
    if (e.key === ' ' || e.key === 'Enter') {
      e.preventDefault();
      this.checked = !this.checked;
      this.dispatchEvent(
        new CustomEvent('change', {
          detail: { checked: this.checked, value: this.value },
          bubbles: true,
          composed: true,
        }),
      );
    }

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