import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import {
  TrashIcon,
  SparklesIcon,
  PaperClipIcon,
  MicrophoneIcon,
  PaperAirplaneIcon,
  ArrowPathIcon,
  DocumentDuplicateIcon,
  ChatBubbleLeftRightIcon,
  CommandLineIcon,
  SunIcon,
  MoonIcon,
} from "@heroicons/react/24/outline";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

// Internal hooks/types
import { useChat } from "./useChat";
import type { ThreadMeta } from "./threads";

// --- Constants & Config ---
const APP_TITLE = "Krishna's Digital Twin";
const BOT_AVATAR =
  "https://api.dicebear.com/9.x/bottts-neutral/svg?seed=Krishna1&backgroundColor=4e67b6";

const SUGGESTIONS = [
  {
    title: "Summarize Experience",
    text: "Give me a 90-second intro to Krishna Vamsi Dhulipalla—recent work, top strengths, and impact.",
    icon: "✨",
  },
  {
    title: "Download Resume",
    text: "Share Krishna’s latest resume and provide a download link.",
    icon: "📄",
  },
  {
    title: "Capabilities",
    text: "What tools and actions can you perform for me?",
    icon: "🛠️",
  },
  {
    title: "Schedule Meeting",
    text: "Schedule a 30-minute meeting with Krishna next week.",
    icon: "📅",
  },
];

// --- Helper: Date Grouping for Sidebar ---
function groupThreadsByDate(threads: ThreadMeta[]) {
  const today = new Date();
  const yesterday = new Date();
  yesterday.setDate(yesterday.getDate() - 1);

  const groups: Record<string, ThreadMeta[]> = {
    Today: [],
    Yesterday: [],
    "Previous 7 Days": [],
    Older: [],
  };

  threads.forEach((t) => {
    const d = new Date(t.lastAt);
    if (d.toDateString() === today.toDateString()) {
      groups["Today"].push(t);
    } else if (d.toDateString() === yesterday.toDateString()) {
      groups["Yesterday"].push(t);
    } else if (d.getTime() > today.getTime() - 7 * 24 * 60 * 60 * 1000) {
      groups["Previous 7 Days"].push(t);
    } else {
      groups["Older"].push(t);
    }
  });

  return groups;
}

// --- Main Component ---
export default function App() {
  const {
    threads,
    active,
    messages,
    setActiveThread,
    newChat,
    clearChat,
    deleteThread,
    send,
    isStreaming,
    hasFirstToken,
  } = useChat();

  const [input, setInput] = useState("");
  const bottomRef = useRef<HTMLDivElement | null>(null);
  const inputRef = useRef<HTMLTextAreaElement | null>(null);
  const prevThreadId = useRef<string | null>(null);

  // Theme toggle logic
  const [theme, setTheme] = useState<"light" | "dark">("light");

  useEffect(() => {
    // Sync theme with HTML class
    if (theme === "dark") {
      document.documentElement.classList.add("dark");
    } else {
      document.documentElement.classList.remove("dark");
    }
  }, [theme]);

  const toggleTheme = () => {
    setTheme((prev) => (prev === "light" ? "dark" : "light"));
  };

  // --- Voice Input Logic ---
  const [isListening, setIsListening] = useState(false);
  const recognitionRef = useRef<any>(null);

  useEffect(() => {
    const SpeechRecognition =
      (window as any).SpeechRecognition ||
      (window as any).webkitSpeechRecognition;
    if (SpeechRecognition) {
      recognitionRef.current = new SpeechRecognition();
      recognitionRef.current.continuous = false;
      recognitionRef.current.interimResults = false;
      recognitionRef.current.lang = "en-US";

      recognitionRef.current.onresult = (event: any) => {
        const transcript = event.results[0][0].transcript;
        setInput((prev) => (prev ? prev + " " + transcript : transcript));
        setIsListening(false);
      };

      recognitionRef.current.onerror = (event: any) => {
        console.error("Speech recognition error", event.error);
        setIsListening(false);
      };

      recognitionRef.current.onend = () => {
        setIsListening(false);
      };
    }
  }, []);

  const toggleListening = useCallback(() => {
    if (!recognitionRef.current) {
      alert("Browser does not support Speech Recognition");
      return;
    }
    if (isListening) {
      recognitionRef.current.stop();
      setIsListening(false);
    } else {
      recognitionRef.current.start();
      setIsListening(true);
    }
  }, [isListening]);

  // Auto-scroll logic
  useEffect(() => {
    const currentThreadId = active?.id ?? null;
    if (currentThreadId !== prevThreadId.current) {
      prevThreadId.current = currentThreadId;
      bottomRef.current?.scrollIntoView({ behavior: "auto" });
    } else {
      bottomRef.current?.scrollIntoView({ behavior: "smooth" });
    }
  }, [messages, active?.id]);

  const sendMessage = useCallback(() => {
    const text = input.trim();
    if (!text || isStreaming) return;
    send(text);
    setInput("");
  }, [input, isStreaming, send]);

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
      if (e.key === "Enter" && !e.shiftKey) {
        e.preventDefault();
        sendMessage();
      }
    },
    [sendMessage],
  );

  const groupedThreads = useMemo(() => groupThreadsByDate(threads), [threads]);

  return (
    <div className="flex h-screen w-screen selection:-text-accent-teal/30">
      {/* Background Ambience / Structural Divs */}
      <div className="fixed inset-0 z-0 pointer-events-none"></div>

      {/* --- Sidebar --- */}
      <aside className="hidden md:flex flex-col w-[280px] z-10 bg-[var(--bg-strong-paper)]/80 backdrop-blur-xl border-r border-[var(--text-soft-ink)]/10 transition-all">
        {/* Header */}
        <div className="p-4 border-b border-[var(--text-soft-ink)]/10">
          <button
            onClick={newChat}
            className="group flex items-center gap-3 w-full px-3 py-2.5 rounded-xl border border-[var(--text-soft-ink)]/10 bg-[var(--bg-panel)] hover:bg-[var(--text-ink)]/5 transition-all duration-200"
          >
            <div className="p-1.5 rounded-lg bg-[var(--accent-blue)]/10 text-[var(--accent-blue)]">
              <SparklesIcon className="w-5 h-5" />
            </div>
            <span
              className="text-sm font-medium font-mono uppercase tracking-wide text-[var(--text-ink)] spider-hover"
              data-text="New Chat"
            >
              New Chat
            </span>
          </button>
        </div>

        {/* History List */}
        <div className="flex-1 overflow-y-auto p-3 space-y-6 scrollbar-thin scrollbar-thumb-[var(--text-soft-ink)]">
          {Object.entries(groupedThreads).map(([label, group]) => {
            if (group.length === 0) return null;
            return (
              <div key={label}>
                <h3
                  className="px-3 mb-2 text-[10px] font-mono uppercase tracking-[0.12em] text-[var(--text-soft-ink)] spider-hover"
                  data-text={label}
                >
                  {label}
                </h3>
                <div className="space-y-0.5">
                  {group.map((t) => (
                    <div
                      key={t.id}
                      onClick={() => setActiveThread(t)}
                      className={`group relative flex items-center gap-2 px-3 py-2 rounded-lg cursor-pointer transition-colors ${
                        active?.id === t.id
                          ? "bg-[var(--text-ink)]/10 text-[var(--text-ink)]"
                          : "text-[var(--text-soft-ink)] hover:bg-[var(--text-ink)]/5 hover:text-[var(--text-ink)]"
                      }`}
                    >
                      <span
                        className="text-sm flex-1 line-clamp-1 break-all spider-hover"
                        data-text={t.title || "New Conversation"}
                        title={t.title || "New Conversation"}
                      >
                        {t.title || "New Conversation"}
                      </span>
                      {/* Delete Action */}
                      <button
                        onClick={(e) => {
                          e.stopPropagation();
                          if (window.confirm("Delete thread?"))
                            deleteThread(t.id);
                        }}
                        className="opacity-0 group-hover:opacity-100 p-1 rounded hover:bg-[var(--accent-rust)]/10 text-[var(--text-soft-ink)] hover:text-[var(--accent-rust)] transition-all z-10"
                      >
                        <TrashIcon className="w-3.5 h-3.5" />
                      </button>
                    </div>
                  ))}
                </div>
              </div>
            );
          })}
        </div>

        {/* Sidebar Footer */}
        <div className="p-4 border-t border-[var(--text-soft-ink)]/10">
          <a
            href="https://github.com/krishna-dhulipalla/LangGraph_ChatBot"
            target="_blank"
            rel="noreferrer"
            className="flex items-center gap-2 text-xs font-mono uppercase tracking-wide text-[var(--text-soft-ink)] hover:text-[var(--text-ink)] transition-colors spider-hover"
            data-text="View Source Code"
          >
            <CommandLineIcon className="w-4 h-4" />
            <span>View Source Code</span>
          </a>
        </div>
      </aside>

      {/* --- Main Chat Area --- */}
      <main className="relative z-10 flex-1 flex flex-col h-full overflow-hidden">
        {/* Top Navigation */}
        <header className="h-16 flex items-center justify-between px-6 border-b border-[var(--text-soft-ink)]/10 bg-[var(--bg-paper)]/60 backdrop-blur-md">
          <div className="flex items-center gap-3">
            <div className="relative">
              <img
                src={BOT_AVATAR}
                alt="Bot"
                className="w-9 h-9 rounded-md border border-[var(--text-soft-ink)]/20 shadow-[2px_2px_0_var(--shadow-blue)]"
              />
              <span className="absolute -bottom-1 -right-1 w-3 h-3 bg-[var(--accent-teal)] border-2 border-[var(--bg-paper)] rounded-full"></span>
            </div>
            <div>
              <h1
                className="text-lg display-heading text-[var(--text-ink)] spider-title font-semibold"
                data-text={APP_TITLE}
              >
                {APP_TITLE}
              </h1>
            </div>
          </div>

          <div className="flex items-center gap-2">
            <button
              onClick={toggleTheme}
              className="p-2 text-[var(--text-soft-ink)] hover:text-[var(--text-ink)] hover:bg-[var(--text-ink)]/5 rounded-full transition-all"
              title="Toggle Theme"
            >
              {theme === "light" ? (
                <MoonIcon className="w-5 h-5" />
              ) : (
                <SunIcon className="w-5 h-5" />
              )}
            </button>
            <button
              onClick={clearChat}
              className="p-2 text-[var(--text-soft-ink)] hover:text-[var(--text-ink)] hover:bg-[var(--text-ink)]/5 rounded-full transition-all"
              title="Clear Chat"
            >
              <ArrowPathIcon className="w-5 h-5" />
            </button>
          </div>
        </header>

        {/* Chat Stream */}
        <div className="flex-1 overflow-y-auto p-4 md:p-8 scroll-smooth">
          {messages.length === 0 ? (
            <div className="h-full flex flex-col items-center justify-center max-w-2xl mx-auto animate-in fade-in duration-500">
              <div className="mt-1 p-2 bg-[var(--bg-panel)] border border-[var(--text-soft-ink)]/10 shadow-[4px_4px_0_var(--shadow-blue),-2px_-2px_0_rgba(186,90,69,0.04)] rotate-3">
                <ChatBubbleLeftRightIcon className="w-10 h-10 text-[var(--accent-blue)] -rotate-3" />
              </div>
              <h2
                className="text-3xl section-title text-[var(--text-ink)] mb-4 spider-title"
                data-text="How can I help you today?"
              >
                How can I help you today?
              </h2>
              <p className="text-[var(--text-soft-ink)] text-sm mb-4 max-w-md text-center leading-relaxed">
                I'm Krishna's digital twin. Ask me about his architecture
                skills, recent projects, or schedule a meeting.
              </p>

              {/* Suggestions Grid */}
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4 w-full">
                {SUGGESTIONS.map((s, i) => (
                  <button
                    key={i}
                    onClick={() => {
                      if (!isStreaming) send(s.text);
                    }}
                    className="group flex items-start gap-4 p-5 bg-[var(--bg-panel)] hover:bg-[var(--bg-strong-paper)] border border-[var(--text-soft-ink)]/10 text-left transition-all hover:-translate-y-1 hover:shadow-[4px_4px_0_var(--shadow-blue)]"
                  >
                    <span className="text-xl inline-block group-hover:scale-110 transition-transform">
                      {s.icon}
                    </span>
                    <div>
                      <div className="text-sm font-semibold font-serif text-[var(--text-ink)] group-hover:text-[var(--accent-blue)] transition-colors">
                        {s.title}
                      </div>
                      <div className="text-xs text-[var(--text-soft-ink)] mt-1 line-clamp-2 leading-relaxed">
                        {s.text}
                      </div>
                    </div>
                  </button>
                ))}
              </div>
            </div>
          ) : (
            <div className="max-w-3xl mx-auto space-y-6">
              {messages.map((m, idx) => (
                <Bubble
                  key={m.id || idx}
                  message={m}
                  isStreaming={isStreaming && idx === messages.length - 1}
                />
              ))}
              {/* Streaming Indicator */}
              {isStreaming && !hasFirstToken && (
                <div className="flex gap-1 ml-14">
                  <span className="w-2 h-2 rounded-full bg-[var(--text-soft-ink)] animate-bounce" />
                  <span className="w-2 h-2 rounded-full bg-[var(--text-soft-ink)] animate-bounce [animation-delay:0.1s]" />
                  <span className="w-2 h-2 rounded-full bg-[var(--text-soft-ink)] animate-bounce [animation-delay:0.2s]" />
                </div>
              )}
              <div ref={bottomRef} className="h-4" />
            </div>
          )}
        </div>

        {/* --- Input Area --- */}
        <div className="p-4 md:p-6 pb-8">
          <div className="max-w-3xl mx-auto relative">
            <div className="relative flex flex-col gap-2 p-2 bg-[var(--bg-strong-paper)]/90 backdrop-blur-xl rounded-2xl border border-[var(--text-soft-ink)]/20 shadow-sm focus-within:ring-1 focus-within:ring-[var(--accent-blue)] transition-all">
              <textarea
                ref={inputRef}
                value={input}
                onChange={(e) => setInput(e.target.value)}
                onKeyDown={handleKeyDown}
                placeholder="Type a message..."
                className="w-full bg-transparent text-[var(--text-ink)] placeholder-[var(--text-soft-ink)] px-4 py-3 min-h-[50px] max-h-[200px] resize-none outline-none text-[15px] leading-relaxed scrollbar-hide font-sans"
                rows={1}
              />

              {/* Input Actions Bar */}
              <div className="flex items-center justify-between px-2 pb-1">
                <div className="flex items-center gap-1">
                  <button
                    className="cursor-not-allowed opacity-50 p-2 text-[var(--text-soft-ink)] hover:text-[var(--text-ink)] hover:bg-[var(--text-ink)]/5 transition-colors"
                    title="Attach file (coming soon)"
                  >
                    <PaperClipIcon className="w-5 h-5" />
                  </button>
                  <button
                    onClick={toggleListening}
                    className={`p-2 transition-all duration-300 ${
                      isListening
                        ? "text-[var(--accent-rust)] bg-[var(--accent-rust)]/10 animate-pulse ring-1 ring-[var(--accent-rust)]/20"
                        : "text-[var(--text-soft-ink)] hover:text-[var(--text-ink)] hover:bg-[var(--text-ink)]/5"
                    }`}
                    title={isListening ? "Stop Listening" : "Voice Input"}
                  >
                    <MicrophoneIcon className="w-5 h-5" />
                  </button>
                </div>

                <button
                  onClick={sendMessage}
                  disabled={!input.trim() || isStreaming}
                  className={`p-2 px-4 rounded-xl flex items-center gap-2 transition-all font-mono uppercase tracking-widest text-xs font-semibold ${
                    input.trim() && !isStreaming
                      ? "bg-[var(--text-ink)] text-[var(--bg-paper)] hover:opacity-90 shadow-sm"
                      : "bg-[var(--text-soft-ink)]/10 text-[var(--text-soft-ink)] cursor-not-allowed"
                  }`}
                >
                  {isStreaming ? (
                    <span className="w-4 h-4 border-2 border-[var(--bg-paper)] border-t-transparent rounded-full animate-spin" />
                  ) : (
                    <>
                      Send
                      <PaperAirplaneIcon className="w-4 h-4 -ml-0.5" />
                    </>
                  )}
                </button>
              </div>
            </div>
          </div>
        </div>
      </main>
    </div>
  );
}

// --- Message Bubble Component ---
function Bubble({
  message,
  isStreaming,
}: {
  message: any;
  isStreaming: boolean;
}) {
  const isUser = message.role === "user";

  return (
    <div
      className={`flex gap-4 ${isUser ? "justify-end" : "justify-start group"}`}
    >
      {!isUser && (
        <div className="shrink-0 flex flex-col gap-2 pt-1">
          <img
            src={BOT_AVATAR}
            alt="AI"
            className="w-8 h-8 rounded border border-[var(--text-soft-ink)]/20 spider-title"
            data-text=""
          />
        </div>
      )}

      <div
        className={`relative max-w-[85%] md:max-w-[80%] px-5 py-4 text-[15px] leading-relaxed transition-all ${
          isUser
            ? "bg-[var(--bg-panel)] border-2 border-[var(--accent-blue)] text-[var(--text-ink)] shadow-[4px_4px_0_var(--shadow-blue)] font-medium"
            : "bg-[var(--bg-strong-paper)] border border-[var(--text-soft-ink)]/20 text-[var(--text-ink)] shadow-[2px_2px_0_rgba(186,90,69,0.04)]"
        }`}
      >
        <ReactMarkdown
          remarkPlugins={[remarkGfm]}
          components={{
            a: ({ ...props }) => (
              <a
                {...props}
                className="text-[var(--accent-blue)] underline underline-offset-4 decoration-[var(--accent-blue)]/30 hover:decoration-[var(--accent-blue)] hover:text-[var(--accent-blue)] inline-block spider-hover"
                data-text={props.children}
                target="_blank"
              />
            ),
            h1: ({ ...props }) => (
              <h1
                className="text-2xl display-heading mt-6 mb-4 spider-title"
                data-text={props.children}
                {...props}
              />
            ),
            h2: ({ ...props }) => (
              <h2
                className="text-xl section-title mt-5 mb-3 spider-title"
                data-text={props.children}
                {...props}
              />
            ),
            h3: ({ ...props }) => (
              <h3
                className="text-lg font-semibold font-serif mt-4 mb-2"
                {...props}
              />
            ),
            code: ({ inline, className, children, ...props }: any) => {
              if (inline)
                return (
                  <code
                    className="bg-[var(--text-soft-ink)]/10 text-[var(--accent-rust)] px-1.5 py-0.5 font-mono text-[13px]"
                    {...props}
                  >
                    {children}
                  </code>
                );
              return (
                <div className="relative group/code">
                  <div
                    className="absolute top-2 right-2 text-[10px] font-mono text-[var(--text-soft-ink)] px-2 py-1 bg-[var(--bg-paper)]/50 uppercase tracking-widest pointer-events-none opacity-50 spider-title"
                    data-text="CODE"
                  >
                    CODE
                  </div>
                  <pre className="bg-[var(--bg-panel)] p-4 border border-[var(--text-soft-ink)]/20 overflow-x-auto my-4 text-sm shadow-inner font-mono text-[var(--text-ink)]">
                    <code className={className} {...props}>
                      {children}
                    </code>
                  </pre>
                </div>
              );
            },
            ul: (props) => (
              <ul
                className="list-disc list-inside ml-2 space-y-1.5 my-3"
                {...props}
              />
            ),
            ol: (props) => (
              <ol
                className="list-decimal list-inside ml-2 space-y-1.5 my-3"
                {...props}
              />
            ),
            p: (props) => <p className="mb-3 last:mb-0" {...props} />,
            strong: (props) => (
              <strong
                className="font-semibold text-[var(--accent-blue)]"
                {...props}
              />
            ),
          }}
        >
          {message.content}
        </ReactMarkdown>

        {/* Actions for Assistant */}
        {!isUser && !isStreaming && (
          <div className="absolute -bottom-8 left-0 opacity-0 group-hover:opacity-100 transition-opacity flex items-center gap-2">
            <ActionButton
              icon={<DocumentDuplicateIcon className="w-3.5 h-3.5" />}
              label="Copy"
              onClick={() => navigator.clipboard.writeText(message.content)}
            />
            <ActionButton
              icon={<ArrowPathIcon className="w-3.5 h-3.5" />}
              label="Regenerate"
              onClick={() => {}}
            />
          </div>
        )}
      </div>
    </div>
  );
}

function ActionButton({
  icon,
  label,
  onClick,
}: {
  icon: any;
  label: string;
  onClick: () => void;
}) {
  return (
    <button
      onClick={onClick}
      className="flex items-center gap-1.5 font-mono text-[10px] uppercase tracking-widest text-[var(--text-soft-ink)] hover:text-[var(--text-ink)] bg-[var(--bg-panel)] border border-[var(--text-soft-ink)]/10 px-2 py-1 transition-colors spider-hover"
      data-text={label}
    >
      {icon} {label}
    </button>
  );
}
