"use client";

import { useState } from "react";
import { Bot, User, Copy, Check } from "lucide-react";
import ReactMarkdown from "react-markdown";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import {
  oneDark,
  oneLight,
} from "react-syntax-highlighter/dist/esm/styles/prism";
import type { ChatMessage as ChatMessageType } from "@/lib/types";
import { useTheme } from "@/hooks/useTheme";

interface ChatMessageProps {
  message: ChatMessageType;
  agentDisplayName?: string;
}

function CopyButton({ code }: { code: string }) {
  const [copied, setCopied] = useState(false);

  const handleCopy = async () => {
    await navigator.clipboard.writeText(code);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  return (
    <button
      onClick={handleCopy}
      className="flex items-center gap-1 text-xs text-zinc-400 hover:text-zinc-200 transition-colors"
      aria-label="Copy code"
    >
      {copied ? <Check size={12} /> : <Copy size={12} />}
      {copied ? "Copied!" : "Copy"}
    </button>
  );
}

function CodeBlock({
  language,
  code,
  isDark,
}: {
  language: string;
  code: string;
  isDark: boolean;
}) {
  return (
    <div className="my-3 overflow-hidden rounded-lg border border-zinc-200 dark:border-zinc-700">
      <div className="flex items-center justify-between bg-zinc-800 dark:bg-zinc-900 px-4 py-1.5">
        <span className="text-xs text-zinc-400">{language || "code"}</span>
        <CopyButton code={code} />
      </div>
      <SyntaxHighlighter
        language={language || "text"}
        style={isDark ? oneDark : oneLight}
        customStyle={{
          margin: 0,
          borderRadius: 0,
          fontSize: "0.8125rem",
          lineHeight: "1.6",
        }}
        PreTag="div"
        codeTagProps={{ style: { fontFamily: "var(--font-mono, monospace)" } }}
      >
        {code}
      </SyntaxHighlighter>
    </div>
  );
}

function MarkdownContent({
  content,
  isDark,
}: {
  content: string;
  isDark: boolean;
}) {
  return (
    <ReactMarkdown
      components={{
        // Strip the default <pre> wrapper so CodeBlock owns its container
        pre({ children }) {
          return <>{children}</>;
        },
        code({ className, children, ...props }) {
          const match = /language-(\w+)/.exec(className || "");
          const codeText = String(children).replace(/\n$/, "");
          if (match) {
            return (
              <CodeBlock language={match[1]} code={codeText} isDark={isDark} />
            );
          }
          // Inline code
          return (
            <code
              className="rounded bg-zinc-100 dark:bg-zinc-800 px-1 py-0.5 text-[0.8125rem] font-mono text-zinc-800 dark:text-zinc-200"
              {...props}
            >
              {children}
            </code>
          );
        },
        h1({ children }) {
          return (
            <h1 className="mt-4 mb-2 text-xl font-bold text-zinc-900 dark:text-zinc-100 first:mt-0">
              {children}
            </h1>
          );
        },
        h2({ children }) {
          return (
            <h2 className="mt-4 mb-1.5 text-lg font-semibold text-zinc-900 dark:text-zinc-100 first:mt-0">
              {children}
            </h2>
          );
        },
        h3({ children }) {
          return (
            <h3 className="mt-3 mb-1 text-base font-semibold text-zinc-900 dark:text-zinc-100 first:mt-0">
              {children}
            </h3>
          );
        },
        h4({ children }) {
          return (
            <h4 className="mt-3 mb-1 text-sm font-semibold text-zinc-900 dark:text-zinc-100 first:mt-0">
              {children}
            </h4>
          );
        },
        p({ children }) {
          return (
            <p className="mb-2 leading-relaxed text-zinc-800 dark:text-zinc-200 last:mb-0">
              {children}
            </p>
          );
        },
        ul({ children }) {
          return (
            <ul className="mb-2 ml-5 list-disc space-y-1 text-zinc-800 dark:text-zinc-200 last:mb-0">
              {children}
            </ul>
          );
        },
        ol({ children }) {
          return (
            <ol className="mb-2 ml-5 list-decimal space-y-1 text-zinc-800 dark:text-zinc-200 last:mb-0">
              {children}
            </ol>
          );
        },
        li({ children }) {
          return <li className="leading-relaxed">{children}</li>;
        },
        blockquote({ children }) {
          return (
            <blockquote className="my-2 border-l-4 border-zinc-300 dark:border-zinc-600 pl-4 text-zinc-600 dark:text-zinc-400 italic">
              {children}
            </blockquote>
          );
        },
        strong({ children }) {
          return (
            <strong className="font-semibold text-zinc-900 dark:text-zinc-100">
              {children}
            </strong>
          );
        },
        em({ children }) {
          return <em className="italic">{children}</em>;
        },
        a({ href, children }) {
          return (
            <a
              href={href}
              target="_blank"
              rel="noopener noreferrer"
              className="text-blue-600 dark:text-blue-400 underline underline-offset-2 hover:text-blue-800 dark:hover:text-blue-300"
            >
              {children}
            </a>
          );
        },
        hr() {
          return (
            <hr className="my-3 border-zinc-200 dark:border-zinc-700" />
          );
        },
        table({ children }) {
          return (
            <div className="my-2 overflow-x-auto">
              <table className="min-w-full border-collapse text-sm">
                {children}
              </table>
            </div>
          );
        },
        thead({ children }) {
          return (
            <thead className="border-b border-zinc-200 dark:border-zinc-700">
              {children}
            </thead>
          );
        },
        th({ children }) {
          return (
            <th className="px-3 py-1.5 text-left font-semibold text-zinc-700 dark:text-zinc-300">
              {children}
            </th>
          );
        },
        td({ children }) {
          return (
            <td className="border-t border-zinc-100 dark:border-zinc-800 px-3 py-1.5 text-zinc-800 dark:text-zinc-200">
              {children}
            </td>
          );
        },
      }}
    >
      {content}
    </ReactMarkdown>
  );
}

export function ChatMessage({
  message,
  agentDisplayName = "Agent",
}: ChatMessageProps) {
  const isUser = message.role === "user";
  const { resolvedTheme } = useTheme();
  const isDark = resolvedTheme === "dark";
  const time = new Date(message.timestamp).toLocaleTimeString([], {
    hour: "2-digit",
    minute: "2-digit",
  });

  return (
    <div
      className={`flex gap-2.5 px-3 py-3 md:gap-3 md:px-4 ${
        isUser ? "" : "bg-zinc-50 dark:bg-zinc-900/50"
      }`}
    >
      <div
        className={`flex h-8 w-8 shrink-0 items-center justify-center rounded-full ${
          isUser
            ? "bg-zinc-200 dark:bg-zinc-700"
            : "bg-blue-100 dark:bg-blue-900/50"
        }`}
      >
        {isUser ? (
          <User size={16} className="text-zinc-600 dark:text-zinc-300" />
        ) : (
          <Bot size={16} className="text-blue-600 dark:text-blue-400" />
        )}
      </div>
      <div className="min-w-0 flex-1">
        <div className="mb-0.5 flex items-center gap-2">
          <span className="text-xs font-medium text-zinc-700 dark:text-zinc-300">
            {isUser ? "You" : agentDisplayName}
          </span>
          <span className="text-xs text-zinc-400 dark:text-zinc-500">
            {time}
          </span>
        </div>
        {isUser ? (
          <div className="whitespace-pre-wrap text-sm text-zinc-800 dark:text-zinc-200">
            {message.text}
          </div>
        ) : (
          <div className="text-sm">
            <MarkdownContent content={message.text} isDark={isDark} />
          </div>
        )}
      </div>
    </div>
  );
}
