import { DeesElement, html, property, customElement, css, type TemplateResult } from '@design.estate/dees-element';
import { idpElementStyles } from './tokens.js';

declare global {
  interface HTMLElementTagNameMap {
    'idp-input': IdpInput;
  }
}

@customElement('idp-input')
export class IdpInput extends DeesElement {
  public static demo = () => html`<idp-input label="Email" placeholder="user@example.com"></idp-input>`;
  public static demoGroups = ['idp.global v3 primitives'];

  @property({ type: String })
  public accessor label = '';

  @property({ type: String })
  public accessor name = '';

  @property({ type: String })
  public accessor key = '';

  @property({ type: String })
  public accessor hint = '';

  @property({ type: String })
  public accessor value = '';

  @property({ type: String })
  public accessor placeholder = '';

  @property({ type: String })
  public accessor type = 'text';

  @property({ type: String })
  public accessor autocomplete = '';

  @property({ type: String })
  public accessor error = '';

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

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

  public static styles = [
    ...idpElementStyles,
    css`
      :host {
        display: block;
      }
      label {
        display: grid;
        gap: 6px;
      }
      .label {
        color: var(--idp-fg);
        font-size: 13px;
        font-weight: 500;
      }
      input {
        width: 100%;
        height: 36px;
        box-sizing: border-box;
        padding: 0 10px;
        border: 1px solid var(--idp-border);
        border-radius: 8px;
        outline: none;
        background: var(--idp-card);
        color: var(--idp-fg);
        font-family: var(--idp-font);
        font-size: 13px;
        transition: border-color 120ms ease, box-shadow 120ms ease;
      }
      input:focus {
        border-color: var(--idp-accent);
        box-shadow: 0 0 0 3px color-mix(in srgb, var(--idp-accent), transparent 86%);
      }
      input:disabled {
        opacity: 0.5;
      }
      input[aria-invalid='true'] {
        border-color: var(--idp-destructive);
        box-shadow: 0 0 0 3px color-mix(in srgb, var(--idp-destructive), transparent 86%);
      }
      .hint,
      .error {
        color: var(--idp-muted-fg);
        font-size: 12px;
        line-height: 1.4;
      }
      .error {
        color: var(--idp-destructive);
      }
    `,
  ];

  public focus() {
    this.shadowRoot?.querySelector('input')?.focus();
  }

  public validate() {
    const input = this.shadowRoot?.querySelector('input');
    if (this.required && !this.value.trim()) {
      this.error = `${this.label || this.name || 'This field'} is required.`;
      return false;
    }

    if (input && !input.checkValidity()) {
      this.error = input.validationMessage;
      return false;
    }

    this.error = '';
    return true;
  }

  private handleInput(eventArg: Event) {
    this.value = (eventArg.target as HTMLInputElement).value;
    if (this.error) {
      this.validate();
    }
    this.dispatchEvent(new CustomEvent('idp-input-change', {
      detail: { name: this.name || this.key, key: this.key || this.name, value: this.value },
      bubbles: true,
      composed: true,
    }));
  }

  public render(): TemplateResult {
    return html`
      <label>
        ${this.label ? html`<span class="label">${this.label}</span>` : html``}
        <input
          .value=${this.value}
          name=${this.name || this.key}
          type=${this.type}
          placeholder=${this.placeholder}
          autocomplete=${this.autocomplete}
          ?required=${this.required}
          ?disabled=${this.disabled}
          aria-invalid=${this.error ? 'true' : 'false'}
          @input=${this.handleInput}
        />
        ${this.error ? html`<span class="error">${this.error}</span>` : this.hint ? html`<span class="hint">${this.hint}</span>` : html``}
      </label>
    `;
  }
}
