"use client";

import React, { createContext, useContext } from "react";
import ReactMarkdown from "react-markdown";
import type { Components } from "react-markdown";
import type { Element } from "hast";

// Lets the `code` renderer know it's inside a `pre` block vs. inline.
// React renders parent-to-child, so the Provider in `pre` is active
// when `code` renders inside it.
const InsidePreContext = createContext(false);

function GoldDot() {
  return (
    <span
      style={{
        width: 8,
        height: 8,
        borderRadius: "50%",
        background: "linear-gradient(135deg, #facc15, #f97316)",
        boxShadow: "0 0 8px rgba(250, 204, 21, 0.7)",
        flexShrink: 0,
        display: "inline-block",
      }}
    />
  );
}

function BlueDot() {
  return (
    <span
      style={{
        width: 8,
        height: 8,
        borderRadius: "50%",
        background: "linear-gradient(135deg, #60a5fa, #34d399)",
        boxShadow: "0 0 8px rgba(96, 165, 250, 0.6)",
        flexShrink: 0,
        display: "inline-block",
      }}
    />
  );
}

function KeyBadge({ children }: { children: React.ReactNode }) {
  return (
    <span
      style={{
        background: "rgba(250, 204, 21, 0.12)",
        border: "1px solid rgba(250, 204, 21, 0.35)",
        borderRadius: 6,
        padding: "1px 10px",
        color: "#fde68a",
        fontWeight: 600,
        fontSize: "0.875rem",
        whiteSpace: "nowrap",
      }}
    >
      {children}
    </span>
  );
}

// Extracts plain text from a HAST element's text children,
// stripping a trailing colon (e.g. "Backend:" → "Backend").
function extractHastText(node: Element): string {
  return (node.children ?? [])
    .filter((c): c is { type: "text"; value: string } => c.type === "text")
    .map((c) => c.value)
    .join("")
    .replace(/:$/, "")
    .trim();
}

const components: Components = {
  h1: ({ children }) => (
    <h1
      style={{
        fontSize: "2.4rem",
        fontWeight: 800,
        margin: "0 0 1.5rem 0",
        background: "linear-gradient(90deg, #facc15, #60a5fa)",
        WebkitBackgroundClip: "text",
        WebkitTextFillColor: "transparent",
        backgroundClip: "text",
        letterSpacing: "-0.02em",
      }}
    >
      {children}
    </h1>
  ),

  h2: ({ children }) => (
    <div style={{ margin: "1.75rem 0 0.75rem 0" }}>
      <h2
        style={{
          fontSize: "1.25rem",
          fontWeight: 700,
          margin: 0,
          background: "linear-gradient(90deg, #facc15, #60a5fa, #34d399)",
          WebkitBackgroundClip: "text",
          WebkitTextFillColor: "transparent",
          backgroundClip: "text",
          letterSpacing: "0.02em",
        }}
      >
        {children}
      </h2>
      <span
        style={{
          display: "block",
          height: 2,
          marginTop: 6,
          background: "linear-gradient(90deg, #facc15, #60a5fa, transparent)",
          borderRadius: 2,
        }}
      />
    </div>
  ),

  h3: ({ children }) => (
    <div style={{ margin: "1.25rem 0 0.5rem 0" }}>
      <h3
        style={{
          fontSize: "1.1rem",
          fontWeight: 600,
          margin: 0,
          background: "linear-gradient(90deg, #facc15, #60a5fa)",
          WebkitBackgroundClip: "text",
          WebkitTextFillColor: "transparent",
          backgroundClip: "text",
        }}
      >
        {children}
      </h3>
      <span
        style={{
          display: "block",
          height: 1,
          marginTop: 4,
          background:
            "linear-gradient(90deg, rgba(250,204,21,0.5), rgba(96,165,250,0.5), transparent)",
          borderRadius: 1,
        }}
      />
    </div>
  ),

  p: ({ children }) => (
    <p
      style={{
        color: "#cbd5e1",
        lineHeight: 1.75,
        margin: "0 0 1.25rem 0",
        fontSize: "1.05rem",
      }}
    >
      {children}
    </p>
  ),

  ul: ({ children }) => (
    <ul
      style={{
        listStyle: "none",
        padding: 0,
        margin: "0 0 1.25rem 0",
        display: "flex",
        flexDirection: "column",
        gap: 9,
      }}
    >
      {children}
    </ul>
  ),

  li: ({ node, children }) => {
    // Inspect HAST to detect the `- **Key:** value` pattern.
    // HAST tagName is always 'strong' regardless of custom component overrides.
    const firstHast = node?.children?.[0];
    const isKeyValue =
      firstHast?.type === "element" &&
      (firstHast as Element).tagName === "strong";

    if (isKeyValue) {
      const keyText = extractHastText(firstHast as Element);
      // Skip the first rendered child (the <strong>) — we replace it with KeyBadge.
      const rest = React.Children.toArray(children).slice(1);
      return (
        <li
          style={{
            display: "flex",
            alignItems: "center",
            gap: 10,
            fontSize: "1rem",
          }}
        >
          <GoldDot />
          <KeyBadge>{keyText}</KeyBadge>
          <span style={{ color: "#94a3b8" }}>{rest}</span>
        </li>
      );
    }

    return (
      <li
        style={{
          display: "flex",
          alignItems: "center",
          gap: 10,
          fontSize: "1rem",
          color: "#e2e8f0",
        }}
      >
        <BlueDot />
        {children}
      </li>
    );
  },

  a: ({ href, children }) => (
    <a
      href={href}
      target={href?.startsWith("http") ? "_blank" : undefined}
      rel={href?.startsWith("http") ? "noopener noreferrer" : undefined}
      style={{
        background: "linear-gradient(90deg, #facc15, #60a5fa)",
        WebkitBackgroundClip: "text",
        WebkitTextFillColor: "transparent",
        backgroundClip: "text",
        fontWeight: 600,
        textDecoration: "underline",
        textDecorationColor: "rgba(250, 204, 21, 0.5)",
        cursor: "pointer",
      }}
    >
      {children}
    </a>
  ),

  strong: ({ children }) => (
    <strong style={{ color: "#fde68a", fontWeight: 700 }}>{children}</strong>
  ),

  em: ({ children }) => (
    <em style={{ color: "#e2e8f0", fontStyle: "italic" }}>{children}</em>
  ),

  // `pre` wraps `code` for fenced code blocks. The Provider lets the
  // nested `code` renderer know it's in a block context (not inline).
  pre: ({ children }) => (
    <InsidePreContext.Provider value={true}>
      <pre
        style={{
          background: "rgba(255, 255, 255, 0.04)",
          border: "1px solid rgba(255, 255, 255, 0.12)",
          borderTop: "2px solid rgba(250, 204, 21, 0.6)",
          borderRadius: "0 0 10px 10px",
          padding: "18px 22px",
          overflowX: "auto",
          margin: "0 0 1.25rem 0",
        }}
      >
        {children}
      </pre>
    </InsidePreContext.Provider>
  ),

  code: ({ children }) => {
    const insidePre = useContext(InsidePreContext);

    if (insidePre) {
      return (
        <code
          style={{
            fontFamily: "var(--font-mono, 'Geist Mono', monospace)",
            fontSize: "0.9rem",
            color: "#e2e8f0",
            lineHeight: 1.65,
          }}
        >
          {children}
        </code>
      );
    }

    // Inline code
    return (
      <code
        style={{
          background: "rgba(250, 204, 21, 0.1)",
          border: "1px solid rgba(250, 204, 21, 0.3)",
          borderRadius: 5,
          padding: "1px 7px",
          color: "#fde68a",
          fontFamily: "var(--font-mono, 'Geist Mono', monospace)",
          fontSize: "0.875em",
        }}
      >
        {children}
      </code>
    );
  },
};

export default function MarkdownContent({ content }: { content: string }) {
  return <ReactMarkdown components={components}>{content}</ReactMarkdown>;
}
