const { useState, useEffect, useRef, useCallback } = React;

/* ============================================================
   作品数据
   ============================================================ */
const CATEGORIES = [
  { id: 'demo', name: '演示视频', icon: 'play', desc: '产品演示、虚拟现实与游戏方向作品展示' },
  { id: 'vlog', name: '口播视频', icon: 'mic', desc: '个人出镜口播类视频作品' },
  { id: 'live', name: '直播切片剪辑', icon: 'scissors', desc: '直播内容精选剪辑与二次创作' },
  { id: 'ai', name: 'AI视频剪辑生成', icon: 'sparkles', desc: '人工智能辅助视频生成与剪辑' },
  { id: 'poster', name: '海报设计', icon: 'image', desc: '平面海报与视觉设计作品' },
  { id: 'audio', name: '音频设计', icon: 'volume', desc: '游戏音频与声音设计作品' },
];

const WORKS = {
  demo: [
    {
      id: 'demo-1',
      title: '微信小程序演示视频',
      desc: '面向二次元周边爱好者的收纳小程序项目演示，展示完整产品交互流程',
      type: 'video',
      src: 'https://aka.doubaocdn.com/s/8rUR9eQeb6',
      duration: '02:30',
    },
    {
      id: 'demo-2',
      title: '女书虚拟现实',
      desc: '虚拟现实方向作品演示，沉浸式文化遗产数字化体验',
      type: 'video',
      src: 'https://aka.doubaocdn.com/s/3I5UYFi8ae',
      duration: '03:15',
    },
    {
      id: 'demo-3',
      title: '《极品飞车》编辑模式地图演示',
      desc: '游戏编辑模式地图创作演示，展示关卡设计与玩家创作系统',
      type: 'video',
      src: 'https://aka.doubaocdn.com/s/Pl8ctUKHNb',
      duration: '04:20',
    },
    {
      id: 'demo-4',
      title: '极品飞车',
      desc: '游戏相关视频作品，赛车游戏实机演示与精彩集锦',
      type: 'video',
      src: 'https://aka.doubaocdn.com/s/mfv5pzcLqJ',
      duration: '01:48',
    },
    {
      id: 'demo-5',
      title: 'AE广告短篇制作',
      desc: 'After Effects影视广告短片制作，动态图形与视觉特效结合',
      type: 'video',
      src: 'https://aka.doubaocdn.com/s/B5VlRXrvjT',
      duration: '00:56',
    },
  ],
  vlog: [
    {
      id: 'vlog-1',
      title: '口播视频1',
      desc: '个人出镜口播作品，自然表达与镜头语言结合',
      type: 'video',
      src: 'https://aka.doubaocdn.com/s/KAQgAAtxLY',
      duration: '02:10',
    },
    {
      id: 'vlog-2',
      title: '口播视频2',
      desc: '叙事型口播创作，内容策划与视觉呈现并重',
      type: 'video',
      src: 'https://aka.doubaocdn.com/s/LleyyVCR7p',
      duration: '03:05',
    },
  ],
  live: [
    {
      id: 'live-1',
      title: '直播切片剪辑',
      desc: '直播精彩内容精选剪辑，节奏把控与二次创作',
      type: 'video',
      src: 'https://aka.doubaocdn.com/s/4koCFoxste',
      duration: '01:32',
    },
  ],
  ai: [
    {
      id: 'ai-1',
      title: 'AI视频方向-重生冷宫',
      desc: 'AI生成视频方向作品，探索人工智能与影像创作的边界',
      type: 'video',
      src: 'https://aka.doubaocdn.com/s/VIPjAobN3U',
      duration: '02:20',
    },
  ],
  poster: [
    {
      id: 'poster-1',
      title: '锦衣卫海报',
      desc: '古风武侠风格「锦衣卫」主题海报，含书法大字与大明红印，传统美学与现代设计融合',
      type: 'image',
      src: 'https://aka.doubaocdn.com/s/oq1Yxjxlqn',
    },
    {
      id: 'poster-2',
      title: 'UI产品设计海报展板',
      desc: '「校园藏宝阁」校园二手交易平台App UI设计展板，含设计规范、功能架构图与界面设计展示',
      type: 'image',
      src: 'https://aka.doubaocdn.com/s/bWBNOmYmnU',
    },
  ],
  audio: [
    {
      id: 'audio-1',
      title: '游戏音频设计',
      desc: '游戏场景音频设计，环境音、音效与音乐的整体听觉体验构建',
      type: 'audio',
      src: 'https://aka.doubaocdn.com/s/wVxcNA8Y6w',
    },
    {
      id: 'audio-2',
      title: '音频设计',
      desc: '综合音频设计作品，涵盖声音设计与音频后期制作',
      type: 'audio',
      src: 'https://aka.doubaocdn.com/s/107sk9NnLO',
    },
  ],
};

/* ============================================================
   SVG 图标组件
   ============================================================ */
const Icons = {
  Play: () => (
    <svg viewBox="0 0 24 24" fill="currentColor">
      <path d="M8 5v14l11-7z" />
    </svg>
  ),
  Clock: () => (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="12" cy="12" r="10" />
      <polyline points="12 6 12 12 16 14" />
    </svg>
  ),
  Video: () => (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <polygon points="23 7 16 12 23 17 23 7" />
      <rect x="1" y="5" width="15" height="14" rx="2" ry="2" />
    </svg>
  ),
  Close: () => (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <line x1="18" y1="6" x2="6" y2="18" />
      <line x1="6" y1="6" x2="18" y2="18" />
    </svg>
  ),
  Menu: () => (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <line x1="3" y1="12" x2="21" y2="12" />
      <line x1="3" y1="6" x2="21" y2="6" />
      <line x1="3" y1="18" x2="21" y2="18" />
    </svg>
  ),
  Phone: () => (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" />
    </svg>
  ),
  Wechat: () => (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" />
    </svg>
  ),
  Mail: () => (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z" />
      <polyline points="22,6 12,13 2,6" />
    </svg>
  ),
  Volume: () => (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" />
      <path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07" />
    </svg>
  ),
};

/* ============================================================
   顶部导航
   ============================================================ */
function Navbar({ activeSection, onNavigate }) {
  const [scrolled, setScrolled] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);

  useEffect(() => {
    const handleScroll = () => {
      setScrolled(window.scrollY > 20);
    };
    window.addEventListener('scroll', handleScroll, { passive: true });
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  const handleClick = (e, id) => {
    e.preventDefault();
    setMenuOpen(false);
    onNavigate(id);
  };

  return (
    <>
      <nav className={`nav ${scrolled ? 'scrolled' : ''}`}>
        <div className="nav-inner">
          <a href="#top" className="nav-brand" onClick={(e) => handleClick(e, 'top')}>
            <div className="nav-brand-mark">文</div>
            <div className="nav-brand-text">
              <span className="nav-brand-name">文雪怡</span>
              <span className="nav-brand-sub">Portfolio</span>
            </div>
          </a>

          <ul className={`nav-links ${menuOpen ? 'open' : ''}`}>
            {CATEGORIES.map((cat) => (
              <li key={cat.id}>
                <a
                  href={`#${cat.id}`}
                  className={`nav-link ${activeSection === cat.id ? 'active' : ''}`}
                  onClick={(e) => handleClick(e, cat.id)}
                >
                  {cat.name}
                </a>
              </li>
            ))}
            <li>
              <a
                href="#contact"
                className={`nav-link ${activeSection === 'contact' ? 'active' : ''}`}
                onClick={(e) => handleClick(e, 'contact')}
              >
                联系方式
              </a>
            </li>
          </ul>

          <button
            className="nav-hamburger"
            onClick={() => setMenuOpen(!menuOpen)}
            aria-label="菜单"
          >
            {menuOpen ? <Icons.Close /> : <Icons.Menu />}
          </button>
        </div>
      </nav>
      <div
        className={`mobile-menu-backdrop ${menuOpen ? 'open' : ''}`}
        onClick={() => setMenuOpen(false)}
      />
    </>
  );
}

/* ============================================================
   Hero 区域
   ============================================================ */
function Hero() {
  return (
    <section className="hero" id="top">
      <div className="hero-decoration">
        {Array.from({ length: 6 }).map((_, i) => (
          <div key={i} className="hero-line" />
        ))}
      </div>

      <div className="hero-content">
        <div className="hero-eyebrow reveal">
          <span className="hero-eyebrow-dot" />
          Digital Media Portfolio
        </div>

        <h1 className="hero-title reveal reveal-delay-1">
          你好，我是
          <br />
          <span className="hero-title-accent">文雪怡</span>
        </h1>

        <p className="hero-subtitle reveal reveal-delay-2">
          数字媒体创作者，专注于视频制作、平面设计与声音艺术。
          用影像讲故事，用设计传情感，用声音造氛围。
        </p>

        <div className="hero-tags reveal reveal-delay-3">
          <span className="hero-tag">视频剪辑</span>
          <span className="hero-tag">影视后期</span>
          <span className="hero-tag">平面设计</span>
          <span className="hero-tag">UI/UX</span>
          <span className="hero-tag">音频设计</span>
          <span className="hero-tag">AI 创作</span>
        </div>
      </div>

      <div className="hero-scroll-hint">
        <span>Scroll</span>
        <div className="hero-scroll-line" />
      </div>
    </section>
  );
}

/* ============================================================
   视频作品卡片
   ============================================================ */
function VideoCard({ work, onPlay }) {
  const videoRef = useRef(null);
  const [hovered, setHovered] = useState(false);
  const [loaded, setLoaded] = useState(false);
  const [videoReady, setVideoReady] = useState(false);
  const [videoError, setVideoError] = useState(false);

  useEffect(() => {
    if (hovered && !loaded && videoRef.current) {
      videoRef.current.src = work.src;
      videoRef.current.load();
      setLoaded(true);
    }
  }, [hovered, loaded, work.src]);

  useEffect(() => {
    if (videoRef.current && loaded && videoReady) {
      if (hovered) {
        videoRef.current.play().catch(() => {});
      } else {
        videoRef.current.pause();
        videoRef.current.currentTime = 0;
      }
    }
  }, [hovered, loaded, videoReady]);

  const handleMouseEnter = () => {
    setHovered(true);
  };

  const handleMouseLeave = () => {
    setHovered(false);
  };

  return (
    <article
      className="work-card reveal"
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
      onClick={() => onPlay(work)}
    >
      <div className="work-card-media">
        <video
          ref={videoRef}
          muted
          playsInline
          preload="none"
          poster=""
          onLoadedData={() => setVideoReady(true)}
          onError={() => setVideoError(true)}
        />
        {!videoReady && (
          <div className="work-card-fallback">
            <div className="work-fallback-icon">
              <Icons.Video />
            </div>
            <span className="work-fallback-text">点击播放视频</span>
          </div>
        )}
        <span className="work-card-badge">视频作品</span>
        <div className="work-card-overlay">
          <div className="work-play-btn">
            <Icons.Play />
          </div>
        </div>
      </div>
      <div className="work-card-body">
        <h3 className="work-card-title">{work.title}</h3>
        <p className="work-card-desc">{work.desc}</p>
        <div className="work-card-meta">
          <span className="work-meta-item">
            <Icons.Clock />
            {work.duration}
          </span>
          <span className="work-meta-item">
            <Icons.Video />
            点击播放
          </span>
        </div>
      </div>
    </article>
  );
}

/* ============================================================
   海报作品卡片
   ============================================================ */
function PosterCard({ work }) {
  return (
    <article className="poster-card reveal">
      <div className="poster-card-media">
        <img src={work.src} alt={work.title} loading="lazy" />
      </div>
      <div className="poster-card-body">
        <h3 className="poster-card-title">{work.title}</h3>
        <p className="poster-card-desc">{work.desc}</p>
      </div>
    </article>
  );
}

/* ============================================================
   音频作品卡片
   ============================================================ */
function AudioCard({ work }) {
  const bars = 12;
  return (
    <article className="audio-card reveal">
      <div className="audio-waveform">
        {Array.from({ length: bars }).map((_, i) => (
          <div key={i} className="audio-bar" style={{ animationDelay: `${i * 0.1}s` }} />
        ))}
      </div>
      <h3 className="audio-card-title">{work.title}</h3>
      <p className="audio-card-desc">{work.desc}</p>
      <div className="audio-player">
        <audio controls src={work.src} preload="none">
          您的浏览器不支持音频播放
        </audio>
      </div>
    </article>
  );
}

/* ============================================================
   作品分区
   ============================================================ */
function WorksSection({ category, works, index, onPlayVideo }) {
  const { id, name, desc } = category;
  const num = String(index + 1).padStart(2, '0');

  const renderWorks = () => {
    if (id === 'poster') {
      return (
        <div className="poster-grid">
          {works.map((w, i) => (
            <div key={w.id} style={{ transitionDelay: `${i * 0.08}s` }} className="reveal">
              <PosterCard work={w} />
            </div>
          ))}
        </div>
      );
    }
    if (id === 'audio') {
      return (
        <div className="audio-grid">
          {works.map((w, i) => (
            <div key={w.id} style={{ transitionDelay: `${i * 0.08}s` }} className="reveal">
              <AudioCard work={w} />
            </div>
          ))}
        </div>
      );
    }
    return (
      <div className="works-grid">
        {works.map((w, i) => (
          <div key={w.id} style={{ transitionDelay: `${i * 0.08}s` }} className="reveal">
            <VideoCard work={w} onPlay={onPlayVideo} />
          </div>
        ))}
      </div>
    );
  };

  return (
    <section className="section" id={id}>
      <div className="section-header">
        <div className="section-title-group">
          <span className="section-eyebrow">Section {num}</span>
          <h2 className="section-title">{name}</h2>
        </div>
        <p className="section-desc">{desc}</p>
      </div>
      {renderWorks()}
    </section>
  );
}

/* ============================================================
   视频弹窗
   ============================================================ */
function VideoModal({ work, onClose }) {
  const videoRef = useRef(null);

  useEffect(() => {
    if (work && videoRef.current) {
      videoRef.current.play().catch(() => {});
    }
  }, [work]);

  useEffect(() => {
    const handleKey = (e) => {
      if (e.key === 'Escape') onClose();
    };
    if (work) {
      document.body.style.overflow = 'hidden';
      window.addEventListener('keydown', handleKey);
    }
    return () => {
      document.body.style.overflow = '';
      window.removeEventListener('keydown', handleKey);
    };
  }, [work, onClose]);

  if (!work) return null;

  return (
    <div className={`video-modal-backdrop ${work ? 'open' : ''}`} onClick={onClose}>
      <div className="video-modal" onClick={(e) => e.stopPropagation()}>
        <div className="video-modal-header">
          <span className="video-modal-title">{work.title}</span>
          <button className="video-modal-close" onClick={onClose} aria-label="关闭">
            <Icons.Close />
          </button>
        </div>
        <div className="video-modal-player">
          <video
            ref={videoRef}
            src={work.src}
            controls
            playsInline
            autoPlay
          >
            您的浏览器不支持视频播放
          </video>
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   页脚
   ============================================================ */
function Footer() {
  return (
    <footer className="footer" id="contact">
      <div className="footer-inner">
        <div className="footer-top">
          <div className="footer-brand">
            <span className="footer-brand-title">Digital Creator</span>
            <h3 className="footer-brand-name">文雪怡</h3>
            <p className="footer-brand-desc">
              数字媒体与视觉设计从业者，热爱用影像、平面与声音创造有温度的作品。
              期待与您的合作，一起打造令人印象深刻的视觉体验。
            </p>
          </div>

          <div>
            <h4 className="footer-col-title">联系方式</h4>
            <ul className="footer-contact-list">
              <li className="footer-contact-item">
                <div className="footer-contact-icon">
                  <Icons.Phone />
                </div>
                <span className="footer-contact-placeholder">（电话 - 面试时提供）</span>
              </li>
              <li className="footer-contact-item">
                <div className="footer-contact-icon">
                  <Icons.Wechat />
                </div>
                <span className="footer-contact-placeholder">（微信 - 面试时提供）</span>
              </li>
              <li className="footer-contact-item">
                <div className="footer-contact-icon">
                  <Icons.Mail />
                </div>
                <span className="footer-contact-placeholder">（邮箱 - 面试时提供）</span>
              </li>
            </ul>
          </div>

          <div>
            <h4 className="footer-col-title">作品分类</h4>
            <ul className="footer-nav-list">
              {CATEGORIES.map((cat) => (
                <li key={cat.id} className="footer-nav-item">
                  <a href={`#${cat.id}`}>{cat.name}</a>
                </li>
              ))}
            </ul>
          </div>
        </div>

        <div className="footer-bottom">
          <p className="footer-copyright">
            © {new Date().getFullYear()} 文雪怡 · 保留所有权利
          </p>
          <p className="footer-tags-line">
            视频剪辑 · 平面设计 · 音频创作 · AI 影像
          </p>
        </div>
      </div>
    </footer>
  );
}

/* ============================================================
   主应用
   ============================================================ */
function App() {
  const [activeSection, setActiveSection] = useState('top');
  const [playingVideo, setPlayingVideo] = useState(null);

  // 滚动联动导航高亮
  useEffect(() => {
    const sectionIds = ['top', ...CATEGORIES.map((c) => c.id), 'contact'];

    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting && entry.intersectionRatio > 0.3) {
            setActiveSection(entry.target.id);
          }
        });
      },
      { threshold: [0.3, 0.5, 0.7], rootMargin: '-100px 0px -40% 0px' }
    );

    sectionIds.forEach((id) => {
      const el = document.getElementById(id);
      if (el) observer.observe(el);
    });

    return () => observer.disconnect();
  }, []);

  // 滚动揭示动画
  useEffect(() => {
    const reveals = document.querySelectorAll('.reveal');
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            entry.target.classList.add('visible');
            observer.unobserve(entry.target);
          }
        });
      },
      { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }
    );

    reveals.forEach((el) => observer.observe(el));
    return () => observer.disconnect();
  }, []);

  const handleNavigate = useCallback((id) => {
    const el = document.getElementById(id);
    if (el) {
      const navHeight = 72;
      const top = el.getBoundingClientRect().top + window.scrollY - navHeight + 1;
      window.scrollTo({ top, behavior: 'smooth' });
    }
  }, []);

  const handlePlayVideo = useCallback((work) => {
    setPlayingVideo(work);
  }, []);

  const handleCloseVideo = useCallback(() => {
    setPlayingVideo(null);
  }, []);

  return (
    <>
      <Navbar activeSection={activeSection} onNavigate={handleNavigate} />
      <main>
        <Hero />
        {CATEGORIES.map((cat, idx) => (
          <React.Fragment key={cat.id}>
            <WorksSection
              category={cat}
              works={WORKS[cat.id]}
              index={idx}
              onPlayVideo={handlePlayVideo}
            />
            {idx < CATEGORIES.length - 1 && <div className="section-divider" />}
          </React.Fragment>
        ))}
      </main>
      <Footer />
      <VideoModal work={playingVideo} onClose={handleCloseVideo} />
    </>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
