"use client";

import { useState } from "react";
import {
  Bot,
  Check,
  ChevronDown,
  Clipboard,
  MessageSquare,
  Sparkles,
  UserRound,
} from "lucide-react";

import { ToolCallBlock } from "@/components/claude/ToolCallBlock";
import { type SessionMessage } from "@/lib/api/claude-code";
import { formatTimestamp } from "@/lib/formatters";
import { cn } from "@/lib/utils";

type SessionMessageThreadProps = {
  messages: SessionMessage[];
};

async function copyText(value: string, onCopied: () => void) {
  if (!value || typeof navigator === "undefined" || !navigator.clipboard) return;
  await navigator.clipboard.writeText(value);
  onCopied();
}

function messageText(message: SessionMessage) {
  return message.text_blocks.map((block) => block.text).join("\n\n");
}

function tokenTotal(message: SessionMessage) {
  if (!message.tokens) return null;
  return (
    message.tokens.input +
    message.tokens.output +
    message.tokens.cache_read +
    message.tokens.cache_write
  );
}

export function SessionMessageThread({ messages }: SessionMessageThreadProps) {
  const [openThinking, setOpenThinking] = useState<Record<string, boolean>>({});
  const [copiedId, setCopiedId] = useState<string | null>(null);

  const markCopied = (id: string) => {
    setCopiedId(id);
    window.setTimeout(() => setCopiedId(null), 1400);
  };

  if (messages.length === 0) {
    return (
      <div className="rounded-2xl border border-dashed border-[color:var(--border-strong)] bg-[color:var(--surface)] p-10 text-center">
        <MessageSquare className="mx-auto h-10 w-10 text-[color:var(--text-muted)]" />
        <h2 className="mt-4 text-lg font-semibold text-[color:var(--text)]">
          No conversation messages
        </h2>
        <p className="mx-auto mt-2 max-w-md text-sm text-[color:var(--text-muted)]">
          This session was found, but there are no displayable user or assistant turns
          in the selected page.
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-5">
      {messages.map((message, index) => {
        const isAssistant = message.role === "assistant";
        const text = messageText(message);
        const thinkingOpen = openThinking[message.uuid] ?? false;
        const tokens = tokenTotal(message);

        return (
          <article
            key={message.uuid}
            id={`message-${message.uuid}`}
            className={cn(
              "scroll-mt-32 rounded-2xl border shadow-sm",
              isAssistant
                ? "border-cyan-400/15 bg-[linear-gradient(180deg,rgba(8,145,178,0.08),rgba(8,145,178,0.02))]"
                : "border-[color:var(--border)] bg-[color:var(--surface)]",
            )}
          >
            <header className="flex flex-wrap items-start justify-between gap-3 border-b border-[color:var(--border)] px-4 py-3 md:px-5">
              <div className="flex min-w-0 items-center gap-3">
                <span
                  className={cn(
                    "flex h-9 w-9 shrink-0 items-center justify-center rounded-xl ring-1",
                    isAssistant
                      ? "bg-cyan-500/15 text-cyan-300 ring-cyan-400/20"
                      : "bg-violet-500/15 text-violet-300 ring-violet-400/20",
                  )}
                >
                  {isAssistant ? (
                    <Bot className="h-4 w-4" />
                  ) : (
                    <UserRound className="h-4 w-4" />
                  )}
                </span>
                <div className="min-w-0">
                  <div className="flex flex-wrap items-center gap-2">
                    <h2 className="text-sm font-semibold text-[color:var(--text)]">
                      {isAssistant ? "Assistant" : "User"}
                    </h2>
                    <span className="rounded-full border border-[color:var(--border)] px-2 py-0.5 text-[11px] font-semibold text-[color:var(--text-muted)]">
                      #{index + 1}
                    </span>
                    {message.model ? (
                      <span className="max-w-[220px] truncate rounded-full bg-[color:var(--surface-muted)] px-2 py-0.5 font-mono text-[11px] text-[color:var(--text-muted)]">
                        {message.model}
                      </span>
                    ) : null}
                  </div>
                  <p className="mt-0.5 text-xs text-[color:var(--text-muted)]">
                    {formatTimestamp(message.timestamp)}
                    {tokens !== null ? ` · ${tokens.toLocaleString()} tokens` : ""}
                  </p>
                </div>
              </div>

              {text ? (
                <button
                  type="button"
                  className="inline-flex h-8 items-center gap-2 rounded-lg border border-[color:var(--border)] px-2.5 text-xs font-semibold text-[color:var(--text-muted)] transition hover:border-[color:var(--accent)] hover:text-[color:var(--accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--accent)]"
                  onClick={() => copyText(text, () => markCopied(message.uuid))}
                >
                  {copiedId === message.uuid ? (
                    <Check className="h-3.5 w-3.5" />
                  ) : (
                    <Clipboard className="h-3.5 w-3.5" />
                  )}
                  {copiedId === message.uuid ? "Copied" : "Copy"}
                </button>
              ) : null}
            </header>

            <div className="space-y-4 px-4 py-4 md:px-5">
              {message.thinking_blocks.length > 0 ? (
                <div className="overflow-hidden rounded-xl border border-amber-400/20 bg-amber-500/10">
                  <button
                    type="button"
                    className="flex w-full items-center justify-between gap-3 px-4 py-3 text-left text-sm font-semibold text-amber-100 transition hover:bg-amber-500/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-amber-300"
                    aria-expanded={thinkingOpen}
                    onClick={() =>
                      setOpenThinking((value) => ({
                        ...value,
                        [message.uuid]: !thinkingOpen,
                      }))
                    }
                  >
                    <span className="flex items-center gap-2">
                      <Sparkles className="h-4 w-4" />
                      Thinking
                    </span>
                    <ChevronDown
                      className={cn("h-4 w-4 transition", thinkingOpen && "rotate-180")}
                    />
                  </button>
                  {thinkingOpen ? (
                    <div className="space-y-3 border-t border-amber-400/20 px-4 py-3">
                      {message.thinking_blocks.map((block, blockIndex) => (
                        <p
                          key={`${message.uuid}-thinking-${blockIndex}`}
                          className="whitespace-pre-wrap break-words text-sm italic leading-7 text-amber-50/90"
                        >
                          {block.text}
                          {block.truncated ? " [truncated]" : ""}
                        </p>
                      ))}
                    </div>
                  ) : null}
                </div>
              ) : null}

              {message.text_blocks.map((block, blockIndex) => (
                <div
                  key={`${message.uuid}-text-${blockIndex}`}
                  className="prose prose-invert max-w-none whitespace-pre-wrap break-words text-[15px] leading-7 text-[color:var(--text)]"
                >
                  {block.text}
                  {block.truncated ? (
                    <span className="ml-2 rounded-full bg-[color:var(--surface-muted)] px-2 py-0.5 text-xs font-semibold text-[color:var(--text-muted)]">
                      truncated
                    </span>
                  ) : null}
                </div>
              ))}

              {message.tool_uses.length > 0 ? (
                <div className="space-y-3">
                  {message.tool_uses.map((tool) => (
                    <ToolCallBlock key={tool.tool_use_id} tool={tool} />
                  ))}
                </div>
              ) : null}
            </div>
          </article>
        );
      })}
    </div>
  );
}
