/**
 * DS Input - Web Component
 *
 * Usage:
 *   <ds-input placeholder="Enter text..." value=""></ds-input>
 *   <ds-input type="password" label="Password"></ds-input>
 *   <ds-input error="This field is required"></ds-input>
 *
 * Attributes:
 *   - type: text | password | email | number | search | tel | url
 *   - placeholder: string
 *   - value: string
 *   - label: string
 *   - error: string
 *   - disabled: boolean
 *   - required: boolean
 *   - icon: string (SVG content or icon name)
 */

class DsInput extends HTMLElement {
  static get observedAttributes() {
    return ['type', 'placeholder', 'value', 'label', 'error', 'disabled', 'required', 'icon', 'tabindex', 'aria-label', 'aria-invalid', 'aria-describedby'];
  }

  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  connectedCallback() {
    this.render();
    this.setupEventListeners();
  }

  disconnectedCallback() {
    this.cleanupEventListeners();
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (this.shadowRoot.innerHTML && oldValue !== newValue) {
      if (name === 'value') {
        const input = this.shadowRoot.querySelector('input');
        if (input && input.value !== newValue) {
          input.value = newValue || '';
        }
      } else {
        this.cleanupEventListeners();
        this.render();
        this.setupEventListeners();
      }
    }
  }

  get type() {
    return this.getAttribute('type') || 'text';
  }

  get placeholder() {
    return this.getAttribute('placeholder') || '';
  }

  get value() {
    const input = this.shadowRoot?.querySelector('input');
    return input ? input.value : (this.getAttribute('value') || '');
  }

  set value(val) {
    this.setAttribute('value', val);
    const input = this.shadowRoot?.querySelector('input');
    if (input) input.value = val;
  }

  get label() {
    return this.getAttribute('label');
  }

  get error() {
    return this.getAttribute('error');
  }

  get disabled() {
    return this.hasAttribute('disabled');
  }

  get required() {
    return this.hasAttribute('required');
  }

  get icon() {
    return this.getAttribute('icon');
  }

  setupEventListeners() {
    const input = this.shadowRoot.querySelector('input');
    if (!input) return;

    // Store handler references for cleanup
    this.inputHandler = (e) => {
      this.dispatchEvent(new CustomEvent('ds-input', {
        bubbles: true,
        composed: true,
        detail: { value: e.target.value }
      }));
    };

    this.changeHandler = (e) => {
      this.dispatchEvent(new CustomEvent('ds-change', {
        bubbles: true,
        composed: true,
        detail: { value: e.target.value }
      }));
    };

    this.focusHandler = () => {
      this.dispatchEvent(new CustomEvent('ds-focus', {
        bubbles: true,
        composed: true
      }));
    };

    this.blurHandler = () => {
      this.dispatchEvent(new CustomEvent('ds-blur', {
        bubbles: true,
        composed: true
      }));
    };

    input.addEventListener('input', this.inputHandler);
    input.addEventListener('change', this.changeHandler);
    input.addEventListener('focus', this.focusHandler);
    input.addEventListener('blur', this.blurHandler);
  }

  cleanupEventListeners() {
    const input = this.shadowRoot?.querySelector('input');
    if (!input) return;

    // Remove all event listeners
    if (this.inputHandler) {
      input.removeEventListener('input', this.inputHandler);
      delete this.inputHandler;
    }
    if (this.changeHandler) {
      input.removeEventListener('change', this.changeHandler);
      delete this.changeHandler;
    }
    if (this.focusHandler) {
      input.removeEventListener('focus', this.focusHandler);
      delete this.focusHandler;
    }
    if (this.blurHandler) {
      input.removeEventListener('blur', this.blurHandler);
      delete this.blurHandler;
    }
  }

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

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

  render() {
    const hasIcon = !!this.icon;
    const hasError = !!this.error;
    const errorClass = hasError ? 'ds-input--error' : '';
    const tabindex = this.disabled ? '-1' : (this.getAttribute('tabindex') || '0');
    const errorId = hasError ? 'error-' + Math.random().toString(36).substr(2, 9) : '';

    // ARIA attributes
    const ariaLabel = this.getAttribute('aria-label') || this.label || '';
    const ariaInvalid = hasError ? 'aria-invalid="true"' : '';
    const ariaDescribedBy = hasError ? `aria-describedby="${errorId}"` : '';

    this.shadowRoot.innerHTML = `
      <link rel="stylesheet" href="/admin-ui/css/tokens.css">
      <link rel="stylesheet" href="/admin-ui/css/components.css">
      <style>
        :host {
          display: block;
        }

        .input-wrapper {
          position: relative;
        }

        .input-wrapper.has-icon input {
          padding-left: 2.5rem;
        }

        .icon {
          position: absolute;
          left: var(--space-3);
          top: 50%;
          transform: translateY(-50%);
          color: var(--muted-foreground);
          pointer-events: none;
          width: 1rem;
          height: 1rem;
        }

        input:focus-visible {
          outline: 2px solid var(--primary);
          outline-offset: 2px;
        }

        .error-text {
          margin-top: var(--space-1);
          font-size: var(--text-xs);
          color: var(--destructive);
        }
      </style>

      ${this.label ? `
        <label class="ds-label ${this.required ? 'ds-label--required' : ''}">
          ${this.label}
        </label>
      ` : ''}

      <div class="input-wrapper ${hasIcon ? 'has-icon' : ''}">
        ${hasIcon ? `<span class="icon" aria-hidden="true">${this.getIconSVG()}</span>` : ''}
        <input
          class="ds-input ${errorClass}"
          type="${this.type}"
          placeholder="${this.placeholder}"
          value="${this.getAttribute('value') || ''}"
          tabindex="${tabindex}"
          aria-label="${ariaLabel}"
          ${ariaInvalid}
          ${ariaDescribedBy}
          ${this.disabled ? 'disabled' : ''}
          ${this.required ? 'required' : ''}
        />
      </div>

      ${hasError ? `<p id="${errorId}" class="error-text" role="alert">${this.error}</p>` : ''}
    `;
  }

  getIconSVG() {
    const icons = {
      search: `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>`,
      email: `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>`,
      lock: `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>`,
      user: `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><circle cx="12" cy="8" r="5"/><path d="M20 21a8 8 0 0 0-16 0"/></svg>`,
    };
    return icons[this.icon] || this.icon || '';
  }
}

customElements.define('ds-input', DsInput);

export default DsInput;
