import axios from "axios";
import { useEffect, useRef, useState } from "react";
import { useNavigate, useParams } from "react-router";
import "./reader.css";
import OutlinedButton from "../md-components/OutlinedButton";
import FilledButton from "../md-components/FilledButton";
import Contents from "../components/contents/Contents";
import Icon from "../md-components/Icon";
import { Link } from "react-router-dom";
import Skeleton from "react-loading-skeleton";
import LinearProgress from "../md-components/LinearProgress";
import {
  addBook,
  getBook,
  getReadBook,
  putReadBook,
  removeBook,
  saveReadBook,
  updateReadBook,
} from "../db";
import IconButton from "../md-components/IconButton";

const ReaderFB2 = () => {
  const { id } = useParams();
  const readerRef = useRef();
  const containerRef = useRef();
  const progressRef = useRef();
  const contentsRef = useRef();
  const contentsBackdropRef = useRef();
  const navigate = useNavigate();

  const [totalHeight, setTotalHeight] = useState(0);
  const [currentHeight, setCurrentHeight] = useState(0);
  const [readerHeight, setReaderHeight] = useState(0);
  const [totalPages, setTotalPages] = useState(1);
  const [currentPage, setCurrentPage] = useState(0);
  const [isLocal, setIsLocal] = useState(false);
  const [onBookshelf, setOnBookshelf] = useState(false);

  const [bookInfo, setBookInfo] = useState({ title: "" });
  const [contents, setContents] = useState([]);

  function nextPage() {
    setCurrentPage((prev) => {
      if (totalPages - prev < 1) {
        return prev;
      }
      return prev + 1;
    });
  }
  function prevPage() {
    setCurrentPage((prev) => {
      if (prev <= 1) {
        return prev;
      }
      return prev - 1;
    });
  }

  const leftRef = useRef();
  const rightRef = useRef();
  function keyboardPagination(e) {
    if (!(leftRef.current && rightRef.current)) {
      console.log("harakiri");
      document.removeEventListener("keydown", keyboardPagination, false);
      return;
    }
    if (e.key === "ArrowRight") {
      rightRef.current.click();
    }
    if (e.key === "ArrowLeft") {
      leftRef.current.click();
    }
  }
  useEffect(() => {
    if (!(leftRef.current && rightRef.current)) return;
    console.log("add listener");
    document.addEventListener("keydown", keyboardPagination, false);
  }, [leftRef, rightRef]);

  function toggleFloatingContents() {
    if (!contentsRef.current || !contentsBackdropRef.current) return;
    contentsRef.current.classList.toggle("show");
    contentsBackdropRef.current.classList.toggle("show");
  }
  useEffect(() => {
    if (currentPage === 0) return;
    if (readerHeight === totalHeight) return;
    setCurrentHeight(readerHeight * (currentPage - 1));
    readerRef.current.scrollTop = readerHeight * (currentPage - 1);
    progressRef.current.style.width = `${(currentPage / totalPages) * 100}%`;
    //console.log(readerHeight * (currentPage-1) / totalHeight, "update read book", currentPage)
    //console.log(readerHeight, currentPage, totalHeight)
    updateReadBook(id, (readerHeight * (currentPage - 1)) / totalHeight);
  }, [currentPage]);

  async function loadBook() {
    let readBook = await getReadBook(id);
    if (readBook) {
      setOnBookshelf(readBook.onBookshelf === true);
    }
    let caches = undefined;
    let localHTML = undefined;
    if (window.caches !== undefined) {
      caches = await window.caches.open("books");
      localHTML = await caches.match(`/api/book/${id}/reader`);
    }
    let localBook = await getBook(id);
    let innerHTML = "";
    if (localBook !== undefined && localHTML !== undefined) {
      setIsLocal(true);
      setBookInfo(localBook);
      setContents(localBook.contents);
      await localHTML.text().then((html) => {
        innerHTML = html;
      });
    } else {
      if (!window.onLine) {
        localStorage.removeItem("lastReadBook");
        navigate("/offline");
      }
      setIsLocal(false);
      axios
        .get(`/book/${id}`)
        .then((res) => setBookInfo(res.data))
        .catch(() => navigate("/notfound"));
      axios.get(`/book/${id}/contents`).then((res) => setContents(res.data));
      await axios.get(`/book/${id}/reader`).then((res) => {
        innerHTML = res.data;
      });
    }
    localStorage.setItem("lastReadBook", id);
    readerRef.current.innerHTML =
      innerHTML +
      "<br>".repeat(Math.floor(containerRef.current.clientHeight / 23) * 2); // заполнение двух страниц пустотой для возможности прокрутки не до конца
    resizingReader(true);
  }
  async function resizingReader(firstLoad) {
    if (!readerRef.current) return;
    if (readerRef.current.scrollHeight === 0) return;
    let progressRatio;
    if (firstLoad) {
      let readBook = await getReadBook(id);
      if (readBook === undefined) {
        progressRatio = 0;
        updateReadBook(id, 0);
      } else {
        progressRatio = readBook.progress;
      }
    }
    readerRef.current.style.height = `${
      Math.floor(containerRef.current.clientHeight / 23) * 23 - 23
    }px`; // подгоняем блок контента под окно ридера, и не забывает учитывать прогресс
    setTotalHeight(readerRef.current.scrollHeight);
    setReaderHeight(readerRef.current.clientHeight);
    setTotalPages(
      Math.ceil(
        readerRef.current.scrollHeight / readerRef.current.clientHeight
      ) - 2
    );

    setCurrentPage(
      Math.ceil(
        Math.floor(progressRatio * readerRef.current.scrollHeight) /
          readerRef.current.clientHeight
      ) + 1
    );
  }

  useEffect(() => {
    if (!readerRef.current) return;
    loadBook();
  }, [id]);
  // изменение размера изображений для соответствия с шириной строки (23px)
  useEffect(() => {
    if (!readerRef.current) return;
    let images = Array.from(readerRef.current.getElementsByTagName("img"));
    images.map((img) => {
      img.height = Math.floor(img.height / 23) * 23;
    });
  }, [totalHeight]);

  return (
    <>
      <div
        className="reader_contents_backdrop"
        ref={contentsBackdropRef}
        onClick={toggleFloatingContents}
      ></div>
      <div className="reader_contents" ref={contentsRef}>
        <Contents
          data={contents}
          readerRef={readerRef}
          readerHeight={readerHeight}
          currentPage={currentPage}
          setCurrentPage={setCurrentPage}
        />
      </div>
      <div style={{ display: "flex", gap: "10px" }} className="mb-4">
        {!(contents.length === 1 && contents[0].title === "") &&
        contents.length !== 0 ? (
          <OutlinedButton
            className="contents_button reader_action_button"
            onClick={toggleFloatingContents}
          >
            <Icon slot="icon">article</Icon>
            Содержание
          </OutlinedButton>
        ) : (
          <></>
        )}
      </div>
      <div className="reader_container" ref={containerRef}>
        <div className="book_content" ref={readerRef} id="reader">
          <LinearProgress indeterminate />
          <br />
          <Skeleton
            count={
              containerRef.current
                ? Math.floor(containerRef.current.clientHeight / 23) - 2
                : 0
            }
          />
        </div>
        <div className="reader_progress" ref={progressRef}></div>
      </div>
      <div
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          gap: "20px",
        }}
      >
        <IconButton
          onClick={prevPage}
          disabled={currentHeight === 0}
          ref={leftRef}
        >
          <Icon>arrow_back</Icon>
        </IconButton>
        <span>
          {currentPage} из {totalPages}
        </span>
        <IconButton
          onClick={nextPage}
          disabled={totalPages - currentPage < 1}
          ref={rightRef}
        >
          <Icon>arrow_forward</Icon>
        </IconButton>
      </div>
    </>
  );
};

export default ReaderFB2;
