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

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: "#f1f5f9",
        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.tagName === "strong";

    if (isKeyValue) {
      const keyText = extractHastText(firstHast);
      // Skip index 0 (the rendered <strong> element) — works because react-markdown
      // emits strong as child[0] for tight lists with the `- **Key:** value` pattern.
      // Tight lists only: loose lists wrap content in <p>, changing the HAST structure.
      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: "#e2e8f0" }}>{rest}</span>
        </li>
      );
    }

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

  a: ({ href, children }) => {
    const isExternal = !!href && /^https?:\/\//.test(href);
    return (
      <a
        href={href}
        target={isExternal ? "_blank" : undefined}
        rel={isExternal ? "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` reads code text directly from the HAST node so `code` renderer
  // is only ever called for inline code — no client-side context needed.
  pre: ({ node }) => {
    const codeEl = node?.children?.[0] as Element | undefined;
    const codeText = (codeEl?.children ?? [])
      .filter((c): c is { type: "text"; value: string } => c.type === "text")
      .map((c) => c.value)
      .join("");
    return (
      <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",
        }}
      >
        <code
          style={{
            fontFamily: "var(--font-mono, 'Geist Mono', monospace)",
            fontSize: "0.9rem",
            color: "#e2e8f0",
            lineHeight: 1.65,
          }}
        >
          {codeText}
        </code>
      </pre>
    );
  },

  // Always inline — block code is handled entirely by the `pre` renderer above.
  code: ({ children }) => (
    <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>;
}
