/**
 * Web Component wrapper for Item
 * Custom element: <hf-item>
 *
 * @generated by scripts/generate-wc-components.ts
 * DO NOT EDIT MANUALLY
 */

import React from 'react';
import { createRoot } from 'react-dom/client';
import { Item } from '../components/molecules/data/Item';

/**
 * Prop type definitions for attribute parsing
 */
const propTypes: Record<string, 'string' | 'number' | 'boolean' | 'json'> = {
    variant: 'string',
    size: 'string',
    title: 'string',
    description: 'string',
    leading: 'json',
    trailing: 'json',
    render: 'json',
    className: 'string'
};

/**
 * Parse attribute value based on expected type
 */
function parseAttr(value: string | null, type: 'string' | 'number' | 'boolean' | 'json'): unknown {
  if (value === null) return undefined;
  switch (type) {
    case 'number': return Number(value);
    case 'boolean': return value !== 'false' && value !== '0';
    case 'json': try { return JSON.parse(value); } catch { return value; }
    default: return value;
  }
}

class ItemWC extends HTMLElement {
  private _root: ReturnType<typeof createRoot> | null = null;
  private _childrenContainer: HTMLDivElement | null = null;
  private _props: Record<string, unknown> = {};
  private _initialized = false;

  connectedCallback() {
    setTimeout(() => this._initialize(), 0);
  }

  private _initialize() {
    if (this._initialized) return;
    this._initialized = true;

    const originalChildren: Node[] = [];
    for (const child of Array.from(this.childNodes)) {
      if (child.nodeType === Node.TEXT_NODE && !child.textContent?.trim()) {
        continue;
      }
      originalChildren.push(child);
    }

    const reactContainer = document.createElement('div');
    reactContainer.style.display = 'contents';

    this._childrenContainer = document.createElement('div');
    this._childrenContainer.style.display = 'contents';

    originalChildren.forEach((child) => this._childrenContainer!.appendChild(child));

    while (this.firstChild) this.removeChild(this.firstChild);
    this.appendChild(reactContainer);

    this._root = createRoot(reactContainer);
    this._render();
  }

  disconnectedCallback() {
    this._root?.unmount();
    this._root = null;
  }

  attributeChangedCallback(_name: string, _oldValue: string | null, _newValue: string | null) {
    this._render();
  }

  static get observedAttributes() {
    return Object.keys(propTypes).map((prop) =>
      prop.replace(/([A-Z])/g, '-$1').toLowerCase(),
    );
  }

  private _setProp(name: string, value: unknown) {
    const propType = propTypes[name] || 'string';
    this._props[name] = this._parseValue(value, propType);
    this._render();
  }

  private _parseValue(value: unknown, type: 'string' | 'number' | 'boolean' | 'json'): unknown {
    if (type === 'boolean' && typeof value === 'boolean') return value;
    if (type === 'number' && typeof value === 'number') return value;
    if (type === 'string' && typeof value === 'string') return value;

    if (typeof value === 'string') {
      switch (type) {
        case 'boolean':
          return value !== 'false' && value !== '0' && value !== '';
        case 'number':
          return Number(value);
        case 'json':
          try { return JSON.parse(value); } catch { return value; }
        default:
          return value;
      }
    }

    return value;
  }

  private _getProp(name: string): unknown {
    if (name in this._props) {
      return this._props[name];
    }
    const attrName = name.replace(/([A-Z])/g, '-$1').toLowerCase();
    const propType = propTypes[name] || 'string';
    return parseAttr(this.getAttribute(attrName), propType);
  }

  private _render() {
    if (!this._root) return;

    const props: Record<string, unknown> = {};
    for (const [propName, propType] of Object.entries(propTypes)) {
      if (propName in this._props) {
        props[propName] = this._props[propName];
      } else {
        const attrName = propName.replace(/([A-Z])/g, '-$1').toLowerCase();
        props[propName] = parseAttr(this.getAttribute(attrName), propType);
      }
    }

    const element = React.createElement(
      Item,
      { ...props, _hostElement: this },
    );

    this._root.render(element);
  }
}

for (const propName of Object.keys(propTypes)) {
  Object.defineProperty(ItemWC.prototype, propName, {
    get() {
      return this._getProp(propName);
    },
    set(value: unknown) {
      this._setProp(propName, value);
    },
    enumerable: true,
    configurable: true,
  });
}

if (typeof customElements !== 'undefined' && !customElements.get('hf-item')) {
  customElements.define('hf-item', ItemWC);
}

export { ItemWC };
export default ItemWC;
