/**
 * Базовый класс для всех компонентов
 */
export class Component {
  constructor(element, options = {}) {
    this.element = element;
    this.options = { ...this.constructor.defaultOptions, ...options };
    this.isInitialized = false;
    this.isDestroyed = false;
    
    // Уникальный ID для компонента
    this.id = this.generateId();
    
    // Хранилище для event listeners
    this.eventListeners = [];
    
    // Привязываем методы к контексту
    this.handleEvent = this.handleEvent.bind(this);
  }

  /**
   * Инициализация компонента
   */
  init() {
    if (this.isInitialized || this.isDestroyed) return;
    
    this.beforeInit();
    this.bindEvents();
    this.afterInit();
    
    this.isInitialized = true;
    this.emit('init');
    
    return this;
  }

  /**
   * Хук перед инициализацией
   */
  beforeInit() {
    // Переопределяется в наследниках
  }

  /**
   * Хук после инициализации
   */
  afterInit() {
    // Переопределяется в наследниках
  }

  /**
   * Привязка событий
   */
  bindEvents() {
    // Переопределяется в наследниках
  }

  /**
   * Добавление event listener с автоматической очисткой
   */
  addEventListener(target, event, handler, options = {}) {
    const actualTarget = typeof target === 'string' ? 
      (target === 'window' ? window : 
       target === 'document' ? document : 
       this.element.querySelector(target)) : target;
    
    if (!actualTarget) {
      console.warn(`Component: Target "${target}" not found`);
      return;
    }

    const boundHandler = handler.bind(this);
    actualTarget.addEventListener(event, boundHandler, options);
    
    // Сохраняем для автоматической очистки
    this.eventListeners.push({
      target: actualTarget,
      event,
      handler: boundHandler,
      options
    });
  }

  /**
   * Универсальный обработчик событий
   */
  handleEvent(event) {
    const methodName = `on${event.type.charAt(0).toUpperCase()}${event.type.slice(1)}`;
    if (typeof this[methodName] === 'function') {
      this[methodName](event);
    }
  }

  /**
   * Испускание кастомного события
   */
  emit(eventName, detail = {}) {
    const event = new CustomEvent(`component:${eventName}`, {
      detail: { component: this, ...detail },
      bubbles: true,
      cancelable: true
    });
    
    this.element.dispatchEvent(event);
    return event;
  }

  /**
   * Поиск элементов внутри компонента
   */
  find(selector) {
    return this.element.querySelector(selector);
  }

  /**
   * Поиск всех элементов внутри компонента
   */
  findAll(selector) {
    return this.element.querySelectorAll(selector);
  }

  /**
   * Добавление CSS класса
   */
  addClass(className) {
    this.element.classList.add(className);
    return this;
  }

  /**
   * Удаление CSS класса
   */
  removeClass(className) {
    this.element.classList.remove(className);
    return this;
  }

  /**
   * Переключение CSS класса
   */
  toggleClass(className, force) {
    this.element.classList.toggle(className, force);
    return this;
  }

  /**
   * Проверка наличия CSS класса
   */
  hasClass(className) {
    return this.element.classList.contains(className);
  }

  /**
   * Установка атрибута
   */
  setAttribute(name, value) {
    this.element.setAttribute(name, value);
    return this;
  }

  /**
   * Получение атрибута
   */
  getAttribute(name) {
    return this.element.getAttribute(name);
  }

  /**
   * Удаление атрибута
   */
  removeAttribute(name) {
    this.element.removeAttribute(name);
    return this;
  }

  /**
   * Получение/установка dataset значений
   */
  dataset(key, value) {
    if (value === undefined) {
      return this.element.dataset[key];
    }
    this.element.dataset[key] = value;
    return this;
  }

  /**
   * Уничтожение компонента
   */
  destroy() {
    if (this.isDestroyed) return;
    
    this.beforeDestroy();
    this.unbindEvents();
    this.afterDestroy();
    
    this.isDestroyed = true;
    this.emit('destroy');
  }

  /**
   * Хук перед уничтожением
   */
  beforeDestroy() {
    // Переопределяется в наследниках
  }

  /**
   * Хук после уничтожения
   */
  afterDestroy() {
    // Переопределяется в наследниках
  }

  /**
   * Очистка всех event listeners
   */
  unbindEvents() {
    this.eventListeners.forEach(({ target, event, handler, options }) => {
      target.removeEventListener(event, handler, options);
    });
    this.eventListeners = [];
  }

  /**
   * Генерация уникального ID
   */
  generateId() {
    return `component-${Math.random().toString(36).substr(2, 9)}`;
  }

  /**
   * Получение информации о компоненте
   */
  getInfo() {
    return {
      id: this.id,
      isInitialized: this.isInitialized,
      isDestroyed: this.isDestroyed,
      className: this.constructor.name,
      elementTag: this.element.tagName.toLowerCase(),
      eventListenersCount: this.eventListeners.length
    };
  }

  /**
   * Статические методы
   */
  static defaultOptions = {};

  /**
   * Создание экземпляра компонента
   */
  static create(element, options = {}) {
    return new this(element, options).init();
  }
}