import { StrictMode, useLayoutEffect, useRef, useState, useEffect } from "react";
import { createRoot } from "react-dom/client";
import { useParams, Navigate, BrowserRouter, Link, Outlet, Route, Routes } from "react-router";
import "./index.css";
import { useShallow } from "zustand/shallow";
import { useStore } from "./store.js";
import {
  ArrowBackIcon,
  ArrowForwardIcon,
  MenuBookIcon,
  MyLocationIcon,
  TitleIcon,
  WidthIcon,
} from "./icons/Icons";

createRoot(document.getElementById("root")).render(
  <StrictMode>
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Layout />}>
          <Route index element={<TopicListView />} />
          <Route path=":topicId" element={<FileReader />} />
        </Route>
      </Routes>
    </BrowserRouter>
  </StrictMode>,
);

function Layout() {
  const params = useParams();
  const topic = useStore((state) => params.topicId && state.topics.byId[params.topicId]);
  const config = useStore((state) => state.config);

  return (
    <div className="max-w-7xl mx-auto h-full relative flex flex-col">
      {config.displayTitle && (
        <div className="w-full px-4 py-2 font-medium text-large text-white bg-blue-600">
          <span>{topic ? `${topic.index + 1}: ${topic.title}` : "Конспект за Държавен Изпит"}</span>
        </div>
      )}
      <Outlet />
    </div>
  );
}

export function TopicListView() {
  const itemRefs = useRef({});
  const topics = useStore(
    useShallow((state) => state.topics.allIds.map((id) => state.topics.byId[id])),
  );
  const selectedTopic = useStore((state) => state.selectedTopic);
  const selectTopic = useStore((state) => state.selectTopic);

  useLayoutEffect(() => {
    if (selectedTopic && selectedTopic.id !== null) {
      itemRefs.current?.[Math.max(selectedTopic.index - 3, 0)].scrollIntoView();
    }
  }, [selectedTopic]);

  return (
    <>
      <div className="flex-1 overflow-y-scroll">
        {topics.map((topic, i) => (
          <Link
            key={topic.id}
            ref={(node) => {
              itemRefs.current[i] = node;
            }}
            to={`/${topic.id}`}
            onClick={() => selectTopic(topic.id)}
            className={`flex px-2 py-1 rounded-md cursor-pointer border-l-4 ${topic.id === selectedTopic?.id ? "bg-blue-100 border-blue-500" : "border-transparent hover:bg-gray-100"}`}
          >
            <div
              className={`w-6 flex-shrink-0 flex font-medium justify-end ${topic.id === selectedTopic?.id ? "text-blue-600" : "text-blue-800"}`}
            >
              {i + 1}
            </div>
            <span className="ml-2">
              <span
                className={`leading-5 ${topic.id === selectedTopic?.id ? "font-medium" : "font-normal"}`}
              >
                {topic.title}
              </span>
            </span>
          </Link>
        ))}
        {selectedTopic !== null && (
          <div className="sticky bottom-0 p-4 w-full flex flex-col">
            <div className="w-full flex justify-between items-center gap-2">
              <Link
                to={`/${selectedTopic.id}`}
                className="w-full p-2 bg-blue-600 hover:bg-blue-700 cursor-pointer truncate rounded-md text-sm text-white text-center shadow-md transition-colors"
              >
                <span>Продължи четенето:</span>
                <br />
                <span className="font-medium">{selectedTopic.title}</span>
              </Link>
              <button
                className="px-3 py-3 bg-teal-500 hover:bg-teal-300 cursor-pointer rounded-full flex items-center justify-center shadow-md transition-colors"
                onClick={() => {
                  itemRefs.current?.[Math.max(selectedTopic.index - 3, 0)].scrollIntoView({
                    behavior: "smooth",
                  });
                }}
              >
                <MyLocationIcon className="h-5 w-5" />
              </button>
            </div>
          </div>
        )}
      </div>
    </>
  );
}

export function FileReader() {
  const params = useParams();
  const topicsById = useStore((state) => state.topics.byId);
  const selectTopic = useStore((state) => state.selectTopic);

  const topic = topicsById[params.topicId];
  if (!topic) {
    return <Navigate to="/" replace />;
  }

  selectTopic(topic.id);

  return <Reader topic={topic} />;
}

export function Reader({ topic }) {
  console.log("render!");
  const config = useStore((state) => state.config);
  const changeConfig = useStore((state) => state.changeConfig);
  const selectedVersion = useStore((state) => state.topicVersions[topic.id] ?? 0);
  const selectVersion = useStore((state) => state.selectTopicVersion);
  const getTopicAtIndex = useStore((state) => state.getTopicAtIndex);

  const prevTopic = getTopicAtIndex(topic.index - 1);
  const nextTopic = getTopicAtIndex(topic.index + 1);

  return (
    <>
      <div className="flex-1">
        <PDFViewer file={topic.files[selectedVersion]} compact={config.narrowMode} />
        <div className="absolute bottom-10 flex justify-between px-4 py-2 w-full z-999">
          <div className="flex space-x-2">
            <Link to="/" className="cursor-pointer p-2 rounded-full bg-blue-600 text-white">
              <MenuBookIcon className="fill-gray-100" />
            </Link>
            <button
              className={`cursor-pointer p-2 rounded-full text-white border ${config.displayTitle ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
              onClick={() => changeConfig({ displayTitle: !config.displayTitle })}
            >
              <TitleIcon className="fill-gray-600" />
            </button>
            {window.innerWidth > 576 && (
              <button
                className={`cursor-pointer p-2 rounded-full text-white border ${config.narrowMode ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
                onClick={() => changeConfig({ narrowMode: !config.narrowMode })}
              >
                <WidthIcon className="fill-gray-600" />
              </button>
            )}
          </div>
          {topic.files.length > 1 && (
            <div className="flex space-x-1">
              {topic.files.map((file, vIndex) => (
                <button
                  key={file}
                  className={`flex-1 cursor-pointer px-2 py-1 rounded-md text-xs whitespace-nowrap ${
                    selectedVersion === vIndex
                      ? "bg-blue-100 text-blue-800 font-medium"
                      : "bg-gray-100 hover:bg-gray-200"
                  }`}
                  onClick={() => selectVersion(topic.id, vIndex)}
                >
                  Версия {vIndex + 1}
                </button>
              ))}
            </div>
          )}
        </div>
      </div>
      <div className="w-full flex flex-col space-y-2">
        <div className="flex bg-gray-100 border-t border-blue-200 text-center">
          {topic.isFirst ? (
            <div className="flex-1 border-r border-blue-200" />
          ) : (
            <Link
              to={`/${prevTopic.id}`}
              className="border-r border-blue-200 w-1/2 flex-1 px-4 py-2 hover:bg-blue-200 cursor-pointer flex align-center justify-start"
            >
              <ArrowBackIcon />
              <span className="ml-2 truncate w-full ">
                {prevTopic.index + 1}: {prevTopic.title}
              </span>
            </Link>
          )}
          {topic.isLast ? (
            <div className="flex-1" />
          ) : (
            <Link
              to={`/${nextTopic.id}`}
              className="flex-1 px-4 py-2 hover:bg-blue-200 w-1/2 cursor-pointer flex align-center justify-end"
            >
              <span className="mr-2 w-full truncate">
                {nextTopic.index + 1}: {nextTopic.title}
              </span>
              <ArrowForwardIcon />
            </Link>
          )}
        </div>
      </div>
    </>
  );
}

export function PDFViewer({ file, compact }) {
  const [content, setContent] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchFile = async () => {
      try {
        setIsLoading(true);
        const response = await fetch(`/files_html/${file}`);

        if (!response.ok) {
          throw new Error(`Failed to load file: ${response.status}`);
        }

        let fileContent = await response.text();

        // If no head tag, add a basic HTML structure with fonts
        fileContent = `
            <!DOCTYPE html>
            <html>
            <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap">
              <style>
                body {
                  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
                  line-height: 1.5;
                  color: #333;
                  -webkit-font-smoothing: antialiased;
                  -moz-osx-font-smoothing: grayscale;
                  padding-bottom: 40px;
                }
                pre, code {
                  font-family: 'SF Mono', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
                }
              </style>
            </head>
            <body>
              ${fileContent}
            </body>
            </html>
          `;

        setContent(fileContent);
        setError(null);
      } catch (err) {
        console.error("Error loading file:", err);
        setError(err.message);
      } finally {
        setIsLoading(false);
      }
    };

    fetchFile();
  }, [file]);

  if (error) {
    return <div className="text-red-500 p-4 border border-red-300 rounded">Error: {error}</div>;
  }

  if (isLoading) {
    return <DelayedLoader />;
  }

  return (
    <div className={`w-full h-full overflow-hidden ${compact ? "max-w-xl mx-auto" : ""}`}>
      <iframe
        srcDoc={content}
        title={`File: ${file}`}
        className="w-full h-full border-0"
        key={file}
        allow="fullscreen"
      />
    </div>
  );
}

const DelayedLoader = ({
  delayMs = 2000,
  className = "p-4 flex justify-center items-center h-40",
  text = "Loading...",
}) => {
  const [showLoader, setShowLoader] = useState(false);

  useEffect(() => {
    // Set a timeout to show the loader after the specified delay
    const timer = setTimeout(() => {
      setShowLoader(true);
    }, delayMs);

    // Clear the timeout on unmount
    return () => clearTimeout(timer);
  }, []); // Empty dependency array - only run on mount

  // Only render if the delay has passed
  if (showLoader) {
    return (
      <div className={className}>
        <div className="animate-pulse">{text}</div>
      </div>
    );
  }

  // Return null before delay threshold
  return null;
};
