import { useEffect, useState, useMemo } from "react";
import ReactMarkdown from "react-markdown";
import rehypeRaw from "rehype-raw";

const toRawUrl = (repoUrl) => {
  if (!repoUrl) return repoUrl;

  if (
    repoUrl.includes("github.com") &&
    !repoUrl.includes("raw.githubusercontent.com")
  ) {
    return repoUrl
      .replace("github.com", "raw.githubusercontent.com")
      .replace("/blob/", "/");
  }

  if (repoUrl.includes("/src/branch/")) {
    return repoUrl.replace("/src/branch/", "/raw/branch/");
  }

  return repoUrl;
};

const getRepoRawBase = (repoUrl) => {
  const rawUrl = toRawUrl(repoUrl);
  if (!rawUrl) return null;

  try {
    const url = new URL(rawUrl);
    const parts = url.pathname.split("/").filter(Boolean);

    if (url.hostname.includes("raw.githubusercontent.com")) {
      return `${url.origin}/${parts.slice(0, 3).join("/")}`;
    }

    const rawIndex = parts.indexOf("raw");
    if (rawIndex !== -1) {
      return `${url.origin}/${parts.slice(0, rawIndex + 2).join("/")}`;
    }

    return null;
  } catch {
    return null;
  }
};

const resolveImageSrc = (src, base) => {
  if (!src) return src;

  if (src.startsWith("http")) return src;

  if (src.includes("/blob/")) {
    return src
      .replace("github.com", "raw.githubusercontent.com")
      .replace("/blob/", "/");
  }

  if (!base) return src;

  const clean = src.replace(/^.\//, "");

  if (src.startsWith("/")) {
    return base + src;
  }

  return `${base}/${clean}`;
};

const fetchREADME = async (repoUrl) => {
  try {
    const rawUrl = toRawUrl(repoUrl);
    const response = await fetch(rawUrl);

    if (!response.ok) {
      throw new Error("Failed to fetch README");
    }

    return await response.text();
  } catch (error) {
    console.error(error);
    return "Error fetching README. Make sure the URL points to a raw markdown file.";
  }
};

export default function ProjectsReadme({ repoUrl }) {
  const [readmeContent, setReadmeContent] = useState("");
  const [isLoading, setIsLoading] = useState(true);

  const base = useMemo(() => getRepoRawBase(repoUrl), [repoUrl]);

  useEffect(() => {
    fetchREADME(repoUrl).then((content) => {
      setReadmeContent(content);
      setIsLoading(false);
    });
  }, [repoUrl]);

  return (
    <div className="w-full max-w-4xl mx-auto p-4 md:p-8 bg-ctp-mantle rounded-xl shadow-sm border border-ctp-text">
      {isLoading ? (
        <div className="flex flex-col gap-3 animate-pulse w-full">
          <div className="h-4 bg-ctp-overlay0 rounded-full w-3/4"></div>
          <div className="h-4 bg-ctp-overlay0 rounded-full w-3/4"></div>
          <div className="h-4 bg-ctp-overlay0 rounded-full w-3/4"></div>
        </div>
      ) : (
        <div className="text-ctp-text leading-relaxed prose prose-base md:prose-lg dark:prose-invert max-w-none">
          <ReactMarkdown
            rehypePlugins={[rehypeRaw]}
            components={{
              code({ className, children, ...props }) {
                const isBlock =
                  className ||
                  (typeof children === "string" && children.includes("\n"));

                if (isBlock) {
                  return (
                    <code
                      className={`${className || ""} text-sm block overflow-x-auto`}
                      {...props}
                    >
                      {children}
                    </code>
                  );
                }

                return (
                  <code
                    className="bg-ctp-mantle px-1.5 py-0.5 rounded text-sm font-mono"
                    {...props}
                  >
                    {children}
                  </code>
                );
              },

              pre({ children, ...props }) {
                return (
                  <pre
                    className="bg-ctp-mantle p-4 rounded-lg overflow-x-auto text-sm my-4"
                    {...props}
                  >
                    {children}
                  </pre>
                );
              },

              h1: ({ children }) => (
                <h1 className="text-3xl font-bold text-ctp-mauve mt-8 mb-4 border-b pb-2 border-ctp-green">
                  {children}
                </h1>
              ),

              h2: ({ children }) => (
                <h2 className="text-2xl font-bold text-ctp-lavender mt-8 mb-4 border-b pb-2 border-ctp-green">
                  {children}
                </h2>
              ),

              h3: ({ children }) => (
                <h3 className="text-xl font-bold text-ctp-lavender mt-5 mb-3">
                  {children}
                </h3>
              ),

              p: ({ children }) => (
                <p className="mb-4 text-ctp-text">{children}</p>
              ),

              ul: ({ children }) => (
                <ul className="list-disc pl-6 mb-4">{children}</ul>
              ),

              ol: ({ children }) => (
                <ol className="list-decimal pl-6 mb-4">{children}</ol>
              ),

              li: ({ children }) => <li className="mb-1">{children}</li>,

              a: ({ children, href }) => (
                <a
                  href={href}
                  target="_blank"
                  rel="noreferrer"
                  className="hover:underline text-ctp-green"
                >
                  {children}
                </a>
              ),

              blockquote: ({ children }) => (
                <blockquote className="border-l-4 border-ctp-text pl-4 py-1 mb-4 bg-ctp-mantle rounded-r-lg">
                  {children}
                </blockquote>
              ),

              img: ({ src, alt }) => {
                const resolved = resolveImageSrc(src, base);

                return (
                  <img
                    src={resolved}
                    alt={alt}
                    className="max-w-full h-auto rounded-lg my-4 shadow-sm"
                    loading="lazy"
                  />
                );
              },
            }}
          >
            {readmeContent}
          </ReactMarkdown>
        </div>
      )}
    </div>
  );
}
