// ДЗ: Рекурсия и Исключения
// задание 1 Рекурсия: HTML tree
{
  function htmlTree(node) {
    // Создаем строку с тегом
    let result = `<${node.tagName}`;

    // Добавляем атрибуты тега
    if (node.attrs) {
      for (let [key, value] of Object.entries(node.attrs)) {
        result += ` ${key}='${value}'`;
      }
    }

    // Добавляем дочерние элементы тега
    result += '>';
    if (node.children) {
      for (let child of node.children) {
        result += htmlTree(child);
      }
    }

    // Закрываем тег
    result += `</${node.tagName}>`;

    return result;
  }
}

{
  // Чтобы вывести сгенерированную HTML-строку на страницу, можно использовать функцию document.write:
  document.write(htmlTree(table));
}

// задание 2 Рекурсия: DOM tree
{
  function domTree(parent, node) {
    // Создаем элемент
    let element = document.createElement(node.tagName);

    // Добавляем атрибуты элемента
    if (node.attrs) {
      for (let [key, value] of Object.entries(node.attrs)) {
        element.setAttribute(key, value);
      }
    }

    // Добавляем дочерние элементы
    if (node.children) {
      for (let child of node.children) {
        domTree(element, child);
      }
    }

    // Добавляем элемент в родителя
    parent.appendChild(element);
  }
}

{
  // Чтобы вызвать функцию, нужно указать родительский элемент DOM и объект с описанием структуры HTML:
  domTree(document.body, table);
}

// задание 3 Рекурсия: Deep Copy
{
  function deepCopy(obj) {
    if (obj == null || typeof obj !== 'object') {
      return obj;
    }

    // Обрабатываем массивы
    if (Array.isArray(obj)) {
      let copy = [];
      for (let item of obj) {
        copy.push(deepCopy(item));
      }
      return copy;
    }

    // Обрабатываем объекты
    let copy = {};
    for (let key of Object.keys(obj)) {
      copy[key] = deepCopy(obj[key]);
    }
    return copy;
  }
}

{
  // Чтобы скопировать массив или объект, нужно вызвать функцию с соответствующим аргументом:
  let arr2 = deepCopy(arr);
  let table2 = deepCopy(table);
}

// задание 4 Рекурсия: My Stringify
{
  function stringify(obj) {
    if (obj == null) {
      return 'null';
    }

    if (typeof obj === 'string') {
      return `"${obj}"`;
    }

    if (typeof obj === 'number' || typeof obj === 'boolean') {
      return obj.toString();
    }

    // Обрабатываем массивы
    if (Array.isArray(obj)) {
      let items = obj.map(stringify);
      return `[${items.join(',')}]`;
    }

    // Обрабатываем объекты
    let properties = Object.keys(obj).map((key) => `"${key}":${stringify(obj[key])}`);
    return `{${properties.join(',')}}`;
  }
}

{
  // Чтобы преобразовать объект в JSON-строку, нужно вызвать функцию с соответствующим аргументом:
  let jsonString = stringify(arr);
}

// задание 5 Рекурсия: getElementById throw
{
  function getElementById(idToFind) {
    function walker(parent) {
      if (!parent || !parent.children) {
        return;
      }

      for (let child of parent.children) {
        if (child.id === idToFind) {
          throw child;
        }
        walker(child);
      }
    }

    try {
      walker(document);
    } catch (element) {
      return element;
    }
  }
}

{
  // Чтобы получить элемент с определенным id, нужно вызвать функцию с соответствующим аргументом:
  let element = getElementById('my-element');
}
