import React from "react";
import ReactMarkdown from "react-markdown";
import rehypeRaw from "rehype-raw";
import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
import { Bot, Download, FileText } from "lucide-react";
import { cn, getInitials } from "@/lib/utils";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { Separator } from "@/components/ui/separator";
import type {
  AiConvAttachment,
  AiConvChannel,
  AiConvMessage,
  AiConvMessageRole,
} from "./types";

function MessageAttachments({
  attachments,
}: {
  attachments: AiConvAttachment[];
}) {
  return (
    <div className="mt-2 flex flex-col gap-1.5">
      {attachments.map((attachment) => (
        <a
          key={attachment.id}
          href={attachment.url ?? "#"}
          download={attachment.url ? attachment.name : undefined}
          onClick={(e) => {
            if (!attachment.url) e.preventDefault();
          }}
          className="flex max-w-[260px] items-center gap-2.5 border border-border bg-muted/60 px-3 py-2 no-underline hover:bg-muted"
        >
          <FileText className="size-4 shrink-0 text-muted-foreground" />
          <div className="flex min-w-0 flex-1 flex-col leading-tight">
            <span className="truncate text-label-small text-foreground">
              {attachment.name}
            </span>
            <span className="text-caption text-muted-foreground">
              {attachment.size}
            </span>
          </div>
          <Download className="size-3.5 shrink-0 text-muted-foreground" />
        </a>
      ))}
    </div>
  );
}

// Strips <style>, <script>, and <head> subtrees entirely so that CSS/JS text
// inside those tags is never surfaced as visible content when rendering
// full HTML email payloads.
const EMAIL_SANITIZE_SCHEMA = {
  ...defaultSchema,
  strip: ["script", "style", "head", ...(defaultSchema.strip ?? [])],
};

// ---------------------------------------------------------------------------
// Internal primitives
// ---------------------------------------------------------------------------

export function BubbleAvatar({
  role,
  senderName,
}: {
  role: AiConvMessageRole;
  senderName?: string;
}) {
  if (role === "bot") {
    return (
      <Avatar size="sm">
        <AvatarFallback className="border border-border bg-muted">
          <Bot className="size-3.5 text-muted-foreground" />
        </AvatarFallback>
      </Avatar>
    );
  }
  if (role === "advisor") {
    return (
      <Avatar size="sm">
        <AvatarFallback className="font-semibold">
          {getInitials(senderName ?? "Advisor")}
        </AvatarFallback>
      </Avatar>
    );
  }
  return (
    <Avatar size="sm">
      <AvatarFallback>{getInitials(senderName ?? "?")}</AvatarFallback>
    </Avatar>
  );
}

function SystemDivider({
  content,
  className,
}: {
  content: string;
  className?: string;
}) {
  return (
    <div className={cn("my-2 flex items-center gap-3 px-2", className)}>
      <Separator className="flex-1" />
      <span className="shrink-0 text-caption text-muted-foreground">
        {content}
      </span>
      <Separator className="flex-1" />
    </div>
  );
}

function ChatMessageBubble({
  message,
  className,
}: {
  message: AiConvMessage;
  className?: string;
}) {
  const { role, content, timestamp, senderName } = message;
  const isAdvisor = role === "advisor";
  const isBot = role === "bot";
  const isVisitor = role === "visitor";

  const displayName = isBot
    ? "AI Assistant"
    : isAdvisor
      ? (senderName ?? "Advisor")
      : (senderName ?? "Lead");

  return (
    <div
      className={cn(
        "flex gap-2.5",
        isAdvisor ? "flex-row-reverse" : "flex-row",
        className,
      )}
    >
      <BubbleAvatar role={role} senderName={senderName} />

      <div
        className={cn(
          "flex max-w-[70%] flex-col gap-1",
          isAdvisor && "items-end",
        )}
      >
        <span className="text-caption text-muted-foreground">
          {displayName}
        </span>

        <div
          className={cn(
            "break-words px-3 py-2 text-body-small leading-relaxed [&_a]:underline [&_p]:m-0",
            isBot &&
              "border border-border bg-muted/60 text-foreground [&_a]:text-primary",
            isVisitor &&
              "border border-border bg-background text-foreground [&_a]:text-primary",
            isAdvisor &&
              "bg-primary text-primary-foreground [&_a]:text-primary-foreground",
          )}
        >
          <ReactMarkdown
            rehypePlugins={[rehypeRaw, [rehypeSanitize, defaultSchema]]}
          >
            {content}
          </ReactMarkdown>
        </div>

        {timestamp && (
          <span className="text-caption text-muted-foreground">
            {timestamp}
          </span>
        )}
      </div>
    </div>
  );
}

function EmailMessageBubble({
  message,
  className,
}: {
  message: AiConvMessage;
  className?: string;
}) {
  const { role, content, timestamp, senderName, subject, attachments } =
    message;
  const isAdvisor = role === "advisor";
  const isBot = role === "bot";

  const displayName = isBot
    ? "AI Assistant"
    : isAdvisor
      ? (senderName ?? "Advisor")
      : (senderName ?? "Lead");

  return (
    <div
      className={cn(
        "flex gap-2.5",
        isAdvisor ? "flex-row-reverse" : "flex-row",
        className,
      )}
    >
      <BubbleAvatar role={role} senderName={senderName} />

      <div
        className={cn(
          "flex w-full max-w-[85%] flex-col gap-1",
          isAdvisor && "items-end",
        )}
      >
        <span className="text-caption text-muted-foreground">
          {displayName}
        </span>

        <div
          className={cn(
            "w-full min-w-0 break-words whitespace-pre-line border border-border bg-background px-4 py-3 text-body-small leading-relaxed [overflow-wrap:anywhere]",
            "[&_p]:mb-2 [&_p:last-child]:mb-0",
            "[&_ul]:mb-2 [&_ul]:list-disc [&_ul]:pl-4",
            "[&_ol]:mb-2 [&_ol]:list-decimal [&_ol]:pl-4",
            "[&_li]:mb-0.5",
            "[&_h1]:mb-2 [&_h1]:text-label-medium",
            "[&_h2]:mb-1.5 [&_h2]:text-label-small",
            "[&_h3]:mb-1 [&_h3]:text-caption",
            "[&_strong]:font-semibold [&_em]:italic",
            "[&_a]:text-primary [&_a]:underline",
            "[&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-3 [&_blockquote]:italic [&_blockquote]:text-muted-foreground",
            "[&_hr]:my-3 [&_hr]:border-border",
            "[&_pre]:whitespace-pre-wrap [&_pre]:break-words [&_pre]:bg-transparent [&_pre]:p-0 [&_pre]:font-[inherit] [&_pre]:text-[length:inherit]",
            "[&_code]:whitespace-pre-wrap [&_code]:break-words [&_code]:bg-transparent [&_code]:p-0 [&_code]:font-[inherit] [&_code]:text-[length:inherit]",
            isAdvisor && "bg-muted/30",
          )}
        >
          {subject && (
            <div className="mb-2.5 border-b border-border pb-2">
              <span className="text-caption text-muted-foreground">
                Subject:
              </span>{" "}
              <span className="text-label-small text-foreground">
                {subject}
              </span>
            </div>
          )}
          <ReactMarkdown
            rehypePlugins={[rehypeRaw, [rehypeSanitize, EMAIL_SANITIZE_SCHEMA]]}
          >
            {content}
          </ReactMarkdown>
          {attachments && attachments.length > 0 && (
            <MessageAttachments attachments={attachments} />
          )}
        </div>

        {timestamp && (
          <span className="text-caption text-muted-foreground">
            {timestamp}
          </span>
        )}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// ChatBubble — public API
// ---------------------------------------------------------------------------

export interface ChatBubbleProps {
  message: AiConvMessage;
  /** Channel the conversation is using — determines chat vs email rendering. */
  channel?: AiConvChannel;
  className?: string;
}

/** Routes to ChatMessageBubble, EmailMessageBubble, or SystemDivider. */
export function ChatBubble({ message, channel, className }: ChatBubbleProps) {
  if (message.role === "system") {
    return <SystemDivider content={message.content} className={className} />;
  }
  if (channel === "email") {
    return <EmailMessageBubble message={message} className={className} />;
  }
  return <ChatMessageBubble message={message} className={className} />;
}
