import React, { useState, useEffect } from "react";
import { MatrixViz } from "../components/MatrixViz";
import { useLanguage } from "../App";
import {
  Play,
  Pause,
  FileText,
  Headphones,
  Zap,
  Volume2,
  X,
} from "lucide-react";

export const BlogPost: React.FC = () => {
  const { language } = useLanguage();
  const [activeSection, setActiveSection] = useState("intro");
  const [activeTab, setActiveTab] = useState<"read" | "listen">("read");
  const [isPlaying, setIsPlaying] = useState(false);
  const [showMiniPlayer, setShowMiniPlayer] = useState(false);

  // Simple scroll spy logic
  useEffect(() => {
    const handleScroll = () => {
      const sections = ["intro", "methods", "results", "discussion"];
      for (const section of sections) {
        const element = document.getElementById(section);
        if (element) {
          const rect = element.getBoundingClientRect();
          if (rect.top >= 0 && rect.top <= 300) {
            setActiveSection(section);
            break;
          }
        }
      }
    };
    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);

  const handleMainPlayPause = () => {
    const newState = !isPlaying;
    setIsPlaying(newState);
    if (newState) {
      setShowMiniPlayer(true);
    }
  };

  const content = {
    en: {
      title: "LoRA Without Regret",
      subtitle: "John Schulman in collaboration with Pradit",
      date: "Sep 29, 2025",
      tldr_title: "Executive Summary (TL;DR)",
      tldr_text:
        "Low-Rank Adaptation (LoRA) is a technique to fine-tune large models efficiently. Our research confirms that while LoRA saves 90% of memory, it can match full fine-tuning performance only if the rank (r) is sufficiently high and alpha scaling is tuned correctly. Ideal for post-training but not pre-training.",
      tabs: { read: "Read Article", listen: "Listen (TTS)" },
      intro_1:
        "Today’s leading language models contain upwards of a trillion parameters, pretrained on tens of trillions of tokens. Base model performance keeps improving with scale, as these trillions are necessary for learning and representing all the patterns in written-down human knowledge.",
      intro_2:
        "In contrast, post-training involves smaller datasets and generally focuses on narrower domains of knowledge and ranges of behavior. It seems wasteful to use a terabit of weights to represent updates from a gigabit or megabit of training data. This intuition has motivated parameter efficient fine-tuning (PEFT), which adjusts a large network by updating a much smaller set of parameters.",
      method_title: "The Method",
      method_1:
        "The leading PEFT method is low-rank adaptation, or LoRA. LoRA replaces each weight matrix W from the original model with a modified version W' = W + γBA, where B and A are matrices that together have far fewer parameters than W, and γ is a constant scaling factor.",
      method_2:
        "In effect, LoRA creates a low-dimensional representation of the updates imparted by fine-tuning. LoRA may offer advantages in the cost and speed of post-training, and there are also a few operational reasons to prefer it to full fine-tuning.",
      results_title: "Operational Advantages",
      results_list: [
        {
          title: "Multi-tenant serving",
          text: "Since LoRA trains an adapter (i.e., the A and B matrices) while keeping the original weights unchanged, a single inference server can keep many adapters in memory.",
        },
        {
          title: "Layout size for training",
          text: "FullFT usually requires an order of magnitude more accelerators than sampling from the same model does.",
        },
        {
          title: "Ease of loading",
          text: "With fewer weights to store, LoRA adapters are fast and easy to set up or transfer between machines.",
        },
      ],
      conclusion_title: "Conclusion",
      conclusion_text:
        "The question remains: can LoRA match the performance of full fine-tuning? Our internal benchmarks suggest yes, provided rank scaling is carefully managed.",
      nav: {
        intro: "Introduction",
        methods: "Methods",
        results: "Results",
        discussion: "Conclusion",
      },
      now_playing: "Now Playing",
      paused: "Paused",
      transcript_title: "Transcript",
    },
    th: {
      title: "LoRA โดยไม่เสียใจ",
      subtitle: "John Schulman ร่วมกับ Pradit (ประดิษฐ์)",
      date: "29 กันยายน 2025",
      tldr_title: "บทสรุปผู้บริหาร (TL;DR)",
      tldr_text:
        "Low-Rank Adaptation (LoRA) เป็นเทคนิคการปรับแต่งโมเดลขนาดใหญ่ที่มีประสิทธิภาพ งานวิจัยของเรายืนยันว่าแม้ LoRA จะประหยัดหน่วยความจำได้ถึง 90% แต่จะให้ผลลัพธ์เทียบเท่าการ Fine-tune แบบเต็มรูปแบบได้ก็ต่อเมื่อค่า Rank (r) สูงเพียงพอและมีการปรับค่า Alpha อย่างถูกต้อง เหมาะสำหรับขั้นตอน Post-training แต่ไม่เหมาะกับ Pre-training",
      tabs: { read: "อ่านบทความ", listen: "ฟังเสียงบรรยาย" },
      intro_1:
        "โมเดลภาษาชั้นนำในปัจจุบันมีพารามิเตอร์มากกว่าล้านล้านตัว ผ่านการฝึกฝนบนข้อมูลมหาศาล ประสิทธิภาพของโมเดลพื้นฐานดีขึ้นเรื่อยๆ ตามขนาด ซึ่งจำเป็นสำหรับการเรียนรู้รูปแบบความรู้ทั้งหมดของมนุษย์",
      intro_2:
        "ในทางตรงกันข้าม การฝึกฝนหลังเสร็จสิ้น (Post-training) มักใช้ชุดข้อมูลขนาดเล็กและเน้นขอบเขตความรู้ที่แคบกว่า ดูเหมือนจะสิ้นเปลืองที่จะใช้น้ำหนักระดับเทราบิตเพื่อแทนการอัปเดตจากข้อมูลเพียงกิกะบิต แนวคิดนี้จึงนำไปสู่การปรับแต่งแบบประหยัดพารามิเตอร์ (PEFT)",
      method_title: "วิธีการ",
      method_1:
        "วิธี PEFT ชั้นนำคือ Low-rank adaptation หรือ LoRA ซึ่งแทนที่เมทริกซ์น้ำหนัก W แต่ละตัวด้วยเวอร์ชันแก้ไข W' = W + γBA โดยที่ B และ A เป็นเมทริกซ์ที่มีพารามิเตอร์น้อยกว่า W มาก",
      method_2:
        "โดยสรุป LoRA สร้างตัวแทนมิติที่ต่ำกว่าของการอัปเดตที่เกิดจากการ Fine-tuning LoRA อาจมีข้อได้เปรียบในด้านต้นทุนและความเร็ว และยังมีเหตุผลด้านการปฏิบัติงานที่ทำให้เป็นที่นิยมมากกว่า Full Fine-tuning",
      results_title: "ข้อได้เปรียบด้านการปฏิบัติงาน",
      results_list: [
        {
          title: "การให้บริการแบบ Multi-tenant",
          text: "เนื่องจาก LoRA ฝึกฝน Adapter (เมทริกซ์ A และ B) โดยไม่เปลี่ยนน้ำหนักเดิม เซิร์ฟเวอร์เดียวจึงสามารถเก็บ Adapter หลายตัวในหน่วยความจำได้",
        },
        {
          title: "ขนาด Layout สำหรับการฝึก",
          text: "FullFT มักต้องการตัวเร่งความเร็ว (GPU/TPU) มากกว่าการสุ่มตัวอย่างจากโมเดลเดียวกันถึงหนึ่งระดับ (Order of magnitude)",
        },
        {
          title: "ความง่ายในการโหลด",
          text: "ด้วยน้ำหนักที่ต้องเก็บน้อยกว่า LoRA adapters จึงตั้งค่าและโอนย้ายระหว่างเครื่องได้รวดเร็ว",
        },
      ],
      conclusion_title: "บทสรุป",
      conclusion_text:
        "คำถามยังคงอยู่: LoRA สามารถทำงานได้เทียบเท่ากับ Full Fine-tuning หรือไม่? การทดสอบภายในของเราชี้ว่า 'ได้' หากมีการจัดการ Rank scaling อย่างระมัดระวัง",
      nav: {
        intro: "บทนำ",
        methods: "วิธีการ",
        results: "ผลลัพธ์",
        discussion: "บทสรุป",
      },
      now_playing: "กำลังเล่น",
      paused: "หยุดชั่วคราว",
      transcript_title: "คำบรรยาย",
    },
  };

  const t = content[language];

  return (
    <div className="bg-paper min-h-screen pb-24 relative">
      {/* Article Header */}
      <header className="pt-24 pb-8 max-w-4xl mx-auto px-6 text-center">
        <h1 className="font-serif text-4xl md:text-5xl text-ink leading-tight mb-6">
          {t.title}
        </h1>
        <div className="font-sans text-sm text-subtle uppercase tracking-widest mb-2">
          {t.subtitle}
        </div>
        <time className="font-serif italic text-subtle">{t.date}</time>

        {/* View Tabs */}
        <div className="flex justify-center mt-12 mb-8">
          <div className="inline-flex bg-gray-100 p-1 rounded-lg border border-gray-200">
            <button
              onClick={() => setActiveTab("read")}
              className={`flex items-center px-6 py-2 rounded-md text-sm font-bold transition-all ${activeTab === "read" ? "bg-white text-ink shadow-sm" : "text-subtle hover:text-ink"}`}
            >
              <FileText size={16} className="mr-2" />
              {t.tabs.read}
            </button>
            <button
              onClick={() => setActiveTab("listen")}
              className={`flex items-center px-6 py-2 rounded-md text-sm font-bold transition-all ${activeTab === "listen" ? "bg-white text-ink shadow-sm" : "text-subtle hover:text-ink"}`}
            >
              <Headphones size={16} className="mr-2" />
              {t.tabs.listen}
            </button>
          </div>
        </div>
      </header>

      {/* TL;DR Section */}
      <div className="max-w-4xl mx-auto px-6 mb-12">
        <div className="bg-blue-50 border border-blue-100 p-6 md:p-8 rounded-sm relative overflow-hidden">
          <div className="absolute top-0 left-0 w-1 h-full bg-accent"></div>
          <div className="flex items-start gap-4">
            <div className="bg-white p-2 rounded-full shadow-sm text-accent shrink-0 mt-1">
              <Zap size={20} />
            </div>
            <div>
              <h3 className="font-sans font-bold text-xs uppercase tracking-widest text-accent mb-2">
                {t.tldr_title}
              </h3>
              <p className="font-serif text-ink leading-relaxed text-base md:text-lg">
                {t.tldr_text}
              </p>
            </div>
          </div>
        </div>
      </div>

      {activeTab === "listen" ? (
        /* Voice Interface */
        <div className="max-w-5xl mx-auto px-4 sm:px-6 animate-in fade-in zoom-in duration-300">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
            {/* Left: Sticky Player */}
            <div className="md:sticky md:top-32 h-fit">
              <div className="bg-[#1e1e1e] rounded-xl p-8 text-center shadow-2xl border border-gray-800">
                <div className="w-20 h-20 bg-gray-800 rounded-full mx-auto mb-6 flex items-center justify-center shadow-inner relative">
                  {isPlaying && (
                    <span className="absolute w-full h-full rounded-full border-2 border-green-500 animate-ping opacity-20"></span>
                  )}
                  <Headphones size={28} className="text-gray-400" />
                </div>

                <h3 className="text-white font-serif text-xl mb-2">
                  {t.title}
                </h3>
                <p className="text-gray-400 font-mono text-[10px] mb-8">
                  Voice: Gemini 2.5 Flash TTS
                </p>

                {/* Fake Waveform */}
                <div className="h-12 flex items-center justify-center gap-1 mb-8 px-4 overflow-hidden">
                  {[...Array(30)].map((_, i) => (
                    <div
                      key={i}
                      className={`w-1 bg-green-500 transition-all duration-150 rounded-full ${isPlaying ? "animate-pulse" : ""}`}
                      style={{
                        height: isPlaying ? `${Math.random() * 100}%` : "10%",
                        opacity: isPlaying ? 1 : 0.3,
                      }}
                    />
                  ))}
                </div>

                <div className="flex items-center justify-center gap-6">
                  <button className="text-gray-400 hover:text-white transition-colors font-mono text-xs">
                    1.0x
                  </button>
                  <button
                    onClick={handleMainPlayPause}
                    className="w-14 h-14 bg-white rounded-full flex items-center justify-center hover:scale-105 transition-transform text-black shadow-lg"
                  >
                    {isPlaying ? (
                      <Pause fill="black" size={20} />
                    ) : (
                      <Play fill="black" size={20} className="ml-1" />
                    )}
                  </button>
                  <button className="text-gray-400 hover:text-white transition-colors font-mono text-xs">
                    -15s
                  </button>
                </div>
              </div>
            </div>

            {/* Right: Scrollable Transcript */}
            <div className="flex flex-col h-[600px]">
              <div className="font-sans text-xs font-bold uppercase tracking-widest text-subtle mb-4 flex items-center gap-2">
                <FileText size={14} /> {t.transcript_title}
              </div>
              <div className="flex-grow overflow-y-auto pr-4 space-y-6 text-subtle font-serif leading-relaxed border-l-2 border-gray-100 pl-6 custom-scrollbar">
                <p className="text-ink font-medium">{t.intro_1}</p>
                <p>{t.intro_2}</p>
                <div className="h-px bg-gray-100 w-full my-4"></div>
                <p className="text-xs font-sans font-bold text-gray-400 uppercase">
                  {t.method_title}
                </p>
                <p>{t.method_1}</p>
                <p>{t.method_2}</p>
                <div className="h-px bg-gray-100 w-full my-4"></div>
                <p className="text-xs font-sans font-bold text-gray-400 uppercase">
                  {t.results_title}
                </p>
                {t.results_list.map((item, idx) => (
                  <p key={idx}>
                    <strong className="text-gray-700">{item.title}:</strong>{" "}
                    {item.text}
                  </p>
                ))}
                <div className="h-px bg-gray-100 w-full my-4"></div>
                <p>{t.conclusion_text}</p>
              </div>
            </div>
          </div>
        </div>
      ) : (
        /* Read Interface */
        <main className="max-w-[1400px] mx-auto px-4 sm:px-6 lg:px-8 grid grid-cols-1 lg:grid-cols-12 gap-12 pb-20">
          {/* Left Sidebar - TOC */}
          <aside className="hidden lg:block lg:col-span-3 relative">
            <nav className="sticky top-32 space-y-4">
              <ul className="font-serif text-sm text-subtle space-y-3 border-l border-gray-200 pl-4">
                <li>
                  <a
                    href="#intro"
                    className={`block transition-colors ${activeSection === "intro" ? "text-ink font-bold" : "hover:text-ink"}`}
                  >
                    {t.nav.intro}
                  </a>
                </li>
                <li>
                  <a
                    href="#methods"
                    className={`block transition-colors ${activeSection === "methods" ? "text-ink font-bold" : "hover:text-ink"}`}
                  >
                    {t.nav.methods}
                  </a>
                </li>
                <li>
                  <a
                    href="#results"
                    className={`block transition-colors ${activeSection === "results" ? "text-ink font-bold" : "hover:text-ink"}`}
                  >
                    {t.nav.results}
                  </a>
                </li>
                <li>
                  <a
                    href="#discussion"
                    className={`block transition-colors ${activeSection === "discussion" ? "text-ink font-bold" : "hover:text-ink"}`}
                  >
                    {t.nav.discussion}
                  </a>
                </li>
              </ul>
            </nav>
          </aside>

          {/* Main Content */}
          <article className="col-span-1 lg:col-span-6 font-serif text-lg leading-relaxed text-gray-800">
            <MatrixViz />

            <section id="intro" className="mb-12">
              <p className="mb-6 first-letter:float-left first-letter:text-7xl first-letter:pr-4 first-letter:font-bold first-letter:text-ink">
                {t.intro_1}
              </p>
              <p className="mb-6">{t.intro_2}</p>
            </section>

            <section id="methods" className="mb-12">
              <h2 className="font-sans font-bold text-xl text-ink mt-12 mb-6">
                {t.method_title}
              </h2>
              <p className="mb-6">{t.method_1}</p>
              <p className="mb-6">{t.method_2}</p>
            </section>

            <section id="results" className="mb-12">
              <h3 className="font-sans font-bold text-lg text-ink mt-8 mb-4">
                {t.results_title}
              </h3>
              <ul className="list-disc list-outside ml-6 space-y-4 mb-6 text-base">
                {t.results_list.map((item, idx) => (
                  <li key={idx}>
                    <strong className="text-ink">{item.title}.</strong>{" "}
                    {item.text}
                  </li>
                ))}
              </ul>
            </section>

            <section id="discussion" className="mb-12">
              <h2 className="font-sans font-bold text-xl text-ink mt-12 mb-6">
                {t.conclusion_title}
              </h2>
              <p className="mb-6">{t.conclusion_text}</p>
            </section>
          </article>

          {/* Right Sidebar - Footnotes */}
          <aside className="hidden lg:block lg:col-span-3 relative">
            <div className="sticky top-32 space-y-12">
              <div className="text-xs text-subtle font-serif leading-relaxed border-l-2 border-gray-100 pl-3">
                <sup className="font-bold mr-1">1</sup>
                Punica: Multi-Tenant LoRA Serving (Chen, Ye, et al, 2023)
              </div>
              <div className="text-xs text-subtle font-serif leading-relaxed border-l-2 border-gray-100 pl-3">
                <sup className="font-bold mr-1">2</sup>
                LoRA: Low-Rank Adaptation of Large Language Models (Hu et al,
                2021)
              </div>
            </div>
          </aside>
        </main>
      )}

      {/* Mini Player Overlay - Persistent if showMiniPlayer is true */}
      {showMiniPlayer && activeTab === "read" && (
        <div className="fixed bottom-6 left-1/2 transform -translate-x-1/2 z-40 animate-in slide-in-from-bottom-4 fade-in">
          <div className="bg-ink text-white pl-4 pr-4 py-3 rounded-full shadow-2xl flex items-center gap-4 border border-gray-700">
            <div className="flex items-center gap-3 border-r border-gray-700 pr-4">
              <div className="relative flex h-3 w-3">
                {isPlaying && (
                  <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span>
                )}
                <span
                  className={`relative inline-flex rounded-full h-3 w-3 ${isPlaying ? "bg-green-500" : "bg-yellow-500"}`}
                ></span>
              </div>
              <div className="flex flex-col">
                <span className="text-[10px] font-sans font-bold uppercase tracking-wider text-gray-400">
                  {isPlaying ? t.now_playing : t.paused}
                </span>
                <span className="text-xs font-bold font-serif truncate max-w-[150px]">
                  {t.title}
                </span>
              </div>
            </div>

            <div className="flex items-center gap-2">
              <button
                onClick={() => setIsPlaying(!isPlaying)}
                className="hover:text-green-400 transition-colors p-1"
                title={isPlaying ? "Pause" : "Play"}
              >
                {isPlaying ? (
                  <Pause size={20} fill="currentColor" />
                ) : (
                  <Play size={20} fill="currentColor" />
                )}
              </button>

              <button
                onClick={() => setActiveTab("listen")}
                className="text-xs font-mono underline hover:text-gray-300 px-2"
              >
                {language === "en" ? "Transcript" : "คำบรรยาย"}
              </button>

              <div className="w-px h-4 bg-gray-700 mx-1"></div>

              <button
                onClick={() => {
                  setIsPlaying(false);
                  setShowMiniPlayer(false);
                }}
                className="text-gray-400 hover:text-red-400 transition-colors p-1"
                title="Close Player"
              >
                <X size={18} />
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};
