import { menuEnum, likeEnum, DEFAULT_AUTHOR } from "../constants/index.js";
import {
  fetchData,
  downloadBook,
  searchByAuthor,
  searchByTag,
  waitForElement,
} from "../requests/index.js";

import { stopPropagation } from "../utils/index.js";
import TagsComponent from "../components/tags/index.js";

export default class BookSection {
  subElements = [];
  element;

  constructor({ url = "" } = {}) {
    this.url = url;
    this.data = [];
    this.render();
  }

  get template() {
    return `
        <div class='main-book__wrapper'>
            <div data-element="body"></div>
            <div class='flowers mh-auto'></div>
        </div>
      `;
  }

  initialize() {
    this.initEventListeners();
  }

  initEventListeners() {
    const booksListener = document.querySelector(".main-book__wrapper");
    booksListener.addEventListener("click", (event) => {
      let id, title;
      const isLike = event.target.closest("[data-like]");
      const isMenu = event.target.closest("[data-menu]");
      const isAction = event.target.closest("[data-action]");
      const isLink = event.target.closest("[data-link]");
      const isAuthor = event.target.closest("[data-author]");
      const isMoreDetails = event.target.closest("[data-details]");
      const isTagWrapper = event.target.closest("[data-tags-wrapper]");
      const isTag = event.target.closest("[data-tag]");

      stopPropagation(event);

      switch (true) {
        case !!isAction:
          id = isAction.dataset.action;
          const { authorid, bookid } =
            isAction.parentNode.parentNode.dataset || {};
          this.makeAction({ id, authorid, bookid });

          break;
        case !!isLike:
          this.makeLike(isLike);
          break;

        case !!isMenu:
          this.openMenu(isMenu);

          break;
        case !!isLink:
          id = isLink.dataset.bookid;
          title = isLink.dataset.title;
          let format = isLink.dataset.format.toLowerCase();
          downloadBook({ id, title, format });

          break;
        case !!isAuthor:
          id = isAuthor.dataset.author;
          this.update({ isByAuthor: true, id });

          break;
        case !!isMoreDetails:
          this.toggleDetails(isMoreDetails);

          break;
        case !isTagWrapper:
          const myEvent = new CustomEvent("outside-click");
          document.dispatchEvent(myEvent);
          this.closeMenu();

          break;
        case !!isTag:
          id = isTag.dataset.tag;
          this.update({ isByTag: true, id });

        default:
          this.closeMenu();

          break;
      }
    });
  }

  destroyEventListeners() {}

  getBookBody(data) {
    return (data || [])
      .map(
        (
          {
            id,
            authors,
            description,
            format,
            genres,
            imageUrl,
            title,
            series,
            subseries,
            year,
            isFavorite,
          },
          index
        ) => {
          const isLast = !!(index === data?.length - 1);
          return `
            <article data-card data-bookid=${id} class="main-book__card card_closed d-fl mb-m mh-auto ${
            isLast ? "last" : ""
          }">
                <div class="main-book__menu_wrapper d-fl">
                    <div class="main-book__menu_like ${
                      isFavorite ? "liked" : "not-liked"
                    }" data-like=${isFavorite} data-bookid=${id}></div>

                      <nav class="main-book__menu main-book__menu_closed" 
                      data-bookid=${id}
                      data-menu></nav>
                </div>
                <div class="main-book__image mr-m">
                    <div class='d-fl'>
                        <div class="main-book__format pr-s">
                          <a class="main-book__link" 
                          data-link 
                          data-bookid=${id} 
                          data-title=${(title || "Unknown")
                            .split(" ")
                            .join("_")}
                          data-format=${format}
                          >${format}</a>
                        </div>
                        <div>
                            <img class="d-bl" src=${
                              imageUrl ? imageUrl : "../web/assets/cover.jpg"
                            } alt="cover" style="width:80px;height:128px;">
                        <p class="second-text no-wrap mv-xs">
                            ${series || "Серия "}
                          </p>
                          <p class="second-text no-wrap mv-xs">
                            ${subseries || "Подсерия"}
                          </p>
                            <div class="second-text mt-s">
                            ${year || "Год неизвестен"}</div>
                        </div>
                    </div>
        
                </div>
                <div class="main-book__description ">
                    <div class="main-book__header">
                        <h3 class="second-text mt-s"><strong>
                        ${title || "Название неизвестно"}</strong></h3>
                        <p>
                          ${this.getAuthors(authors)}
                        </p>
                    </div>
                    <div class="main-book__body body_closed mb-m mt-s">
                        <div data-tags-wrapper class="main-book__tags_wrapper"></div>
                        <div>
                            <span class="second-text">
                            ${description || "Нет описания"}</span>
                        </div>
                    </div>
                </div>
                <div class="main-book__arrow_wrapper w-100 hidden closed">
                  <div data-details class="main-book__arrow">
                    <div class="main-book__arrow-top"></div>
                    <div class="main-book__arrow-bottom"></div>
                  </div>
                </div>

            </article>`;
        }
      )
      .join("");
  }

  getEmptyBody() {
    return `
        <article class="no-book__card d-fl mb-m mh-auto">
            <div class="mh-auto">Ничего не найдено</div>
        </article>`;
  }

  getMenuBody() {
    return menuEnum
      .map(({ label, id }) => {
        return `
        <li class="main-book__action second-text" id="main-book__action" data-action=${id}>
          ${label}
        </li>`;
      })
      .join("");
  }

  getAuthors(authors) {
    return (authors || [DEFAULT_AUTHOR])
      .map(({ id, name }) => {
        return `<a class="main-card__author main-book__link second-text mt-s" data-author=${id}>
        ${name || ""}&nbsp;&nbsp;</a>`;
      })
      .join("");
  }

  openMenu(element) {
    this.closeMenu();
    element.classList.remove("main-book__menu_closed");

    const divElement = document.createElement("ul");
    divElement.innerHTML = this.getMenuBody();

    element.append(divElement);
    element.classList.add("main-book__menu_opened");
  }

  closeMenu() {
    const elements = document.querySelectorAll(".main-book__menu_opened");

    if (elements && elements.length) {
      for (const subElement of elements) {
        subElement.firstElementChild.remove();
        subElement.classList.remove("main-book__menu_opened");
        subElement.classList.add("main-book__menu_closed");
      }
    }
  }

  toggleDetails(element) {
    const isOpened = element.classList.contains("opened");
    const article = element.parentNode.parentNode;
    const article_body = article.querySelector(".main-book__body");

    if (isOpened) {
      element.classList.remove("opened");
      article.classList.add("card_closed");
      article_body.classList.remove("body_opened");
      article_body.classList.add("body_closed");
    } else {
      element.classList.add("opened");
      article.classList.remove("card_closed");
      article_body.classList.remove("body_closed");
      article_body.classList.add("body_opened");
    }
  }

  async countHeight() {
    await waitForElement(".last");

    const articles = document.querySelectorAll("[data-card]");
    articles.forEach((article, i) => {
      const tagWrapper = article.querySelector(".main-book__tags_wrapper");
      const bookid = article.dataset.bookid;
      const { tags } = this.data[i] || [];
      const tagsComponent = new TagsComponent({ tags, article, bookid });

      tagWrapper.append(tagsComponent.element);

      if (article.scrollHeight > 502) {
        const arrow = article.querySelector(".main-book__arrow_wrapper");
        arrow.classList.remove("hidden");
      }
    });
  }

  async makeAction({ id, bookid }) {
    this.element.classList.add("blur", "spinner");

    if (menuEnum[id].action) {
      const data = await menuEnum[id].action({ id, bookid });
    } else {
      alert("Напиши меня");
    }

    this.element.classList.remove("spinner");
    this.closeMenu();
  }

  async makeLike(element) {
    this.element.classList.add("blur", "spinner");

    const { bookid: likedBookId, like } = element.dataset || {};
    const isLiked = like === "true";
    if (!isLiked) {
      await likeEnum[0].action({ bookid: likedBookId });
      element.classList.remove("not-liked");
      element.classList.add("liked");
    } else {
      await likeEnum[1].action({ bookid: likedBookId });
      element.classList.remove("liked");
      element.classList.add("not-liked");
    }

    element.dataset.like = !isLiked;
    this.data = this.data.map(({ isFavorite, id, ...rest }) =>
      likedBookId === id
        ? { id, isFavorite: !isFavorite, ...rest }
        : {
            id,
            isFavorite,
            ...rest,
          }
    );
    console.log("new data", this.data);
    this.element.classList.remove("spinner");
  }

  async update(params) {
    this.element.classList.add("blur", "spinner");

    if (params?.isByAuthor) {
      this.data = await searchByAuthor({ id: params.id });
    } else if (params?.isByTag) {
      this.data = await searchByTag({ id: params.id });
    } else {
      const query = params;
      this.data = await fetchData({ query, url: this.url });
    }
    console.log("data", this.data);

    if (this.data && Object.values(this.data).length) {
      this.subElements.body.innerHTML = this.getBookBody(this.data);
      this.initialize();
    } else {
      this.subElements.body.innerHTML = this.getEmptyBody();
    }
    await this.countHeight();
    this.element.classList.remove("spinner");
  }

  getSubElements(element) {
    const result = {};
    const elements = element.querySelectorAll("[data-element]");

    for (const subElement of elements) {
      const name = subElement.dataset.element;
      result[name] = subElement;
    }
    return result;
  }

  render() {
    const divElement = document.createElement("div");

    divElement.innerHTML = this.template;

    this.element = divElement.firstElementChild;
    this.subElements = this.getSubElements(this.element);
  }

  remove() {
    if (this.element) {
      this.element.remove();
      destroyEventListeners();
    }
  }

  destroy() {
    this.remove();
    this.element = null;
  }
}

// this.data = [
//   {
//     id: "2",
//     authors: [{ id: "1", name: "123" }],
//     description:
//       "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
//     format: "123",
//     genres: [],
//     imageUrl: "",
//     title: "What is Lorem Ipsum?",
//     series: [],
//     subseries: [],
//     year: 1992,
//     tags: [
//         { id: 1, name: "Интересно" },
//         { id: 22, name: "Почитать" },
//         { id: 155, name: "Рекомендовали" },
//         { id: 166, name: "завтра" },
//         { id: 11, name: "наверное" },
//         { id: 221, name: "Почитданетать" },
//         { id: 1515, name: "раздватри" },
//         { id: 1661, name: "возможно" },
//     ],
//     isFavorite: true,
//   },
//   {
//     id: "22",
//     authors: [{ id: "1", name: "123" }],
//     description:
//       "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
//     format: "123",
//     genres: [],
//     imageUrl: "",
//     title: "dsfwqedwqefrwef",
//     series: [],
//     subseries: [],
//     year: 1992,
//     tags: [
//         { id: 1, name: "Интересно" },
//         { id: 22, name: "Почитать" },
//         { id: 155, name: "Рекомендовали" },
//     ],
//     isFavorite: true,
//   },
// ];
