import React, { useCallback, useEffect, useRef, useState } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { tokens } from '@fluentui/react-components';
import { MainLayout } from './layouts/MainLayout';
import About from './components/About';
import CreatePost from './components/CreatePost';
import PostCard from './components/PostCard';
import { fetchArticles, type Article } from './api';
import { useLayout } from './context/LayoutContext';
import './App.css';

const Home: React.FC = () => {
  const { refreshTrigger } = useLayout();
  const [articles, setArticles] = useState<Article[]>([]);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const [hasMore, setHasMore] = useState(true);
  const [homeRefreshTick, setHomeRefreshTick] = useState(0);
  const [refreshing, setRefreshing] = useState(false);
  const observer = useRef<IntersectionObserver | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const lastRefreshAtRef = useRef<number>(0);
  const REFRESH_COOLDOWN_MS = 5000;

  const lastArticleRef = useCallback((node: HTMLDivElement | null) => {
    if (loading) return;
    if (observer.current) observer.current.disconnect();
    observer.current = new IntersectionObserver(entries => {
      if (entries[0].isIntersecting && hasMore) {
        setPage(prevPage => prevPage + 1);
      }
    });
    if (node) observer.current.observe(node);
  }, [loading, hasMore]);

  const doRefresh = useCallback(() => {
    if (refreshing || loading) return;
    const now = Date.now();
    if (now - lastRefreshAtRef.current < REFRESH_COOLDOWN_MS) return;
    lastRefreshAtRef.current = now;
    setRefreshing(true);
    setArticles([]);
    setHasMore(true);
    setPage(1);
    setHomeRefreshTick(t => t + 1);
    if (containerRef.current) containerRef.current.scrollTop = 0;
  }, [refreshing, loading]);

  const onWheel: React.WheelEventHandler<HTMLDivElement> = (e) => {
    const atTop = (containerRef.current?.scrollTop ?? 0) <= 0;
    if (atTop && e.deltaY < 0) {
      doRefresh();
    }
  };

  useEffect(() => {
    if (refreshTrigger > 0) {
      doRefresh();
    }
  }, [refreshTrigger, doRefresh]);

  useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;

    const loadArticles = async () => {
      if (!hasMore) return;
      setLoading(true);
      try {
        const newArticles = await fetchArticles(page, signal);
        if (newArticles.length === 0) {
          setHasMore(false);
        } else {
          setArticles(prev => [...prev, ...newArticles]);
        }
      } catch (error) {
        if (error instanceof Error && error.name !== 'AbortError') {
          console.error('Failed to load articles:', error);
        }
      } finally {
        setLoading(false);
        if (refreshing) {
          setRefreshing(false);
        }
      }
    };

    loadArticles();
    return () => controller.abort();
  }, [page, hasMore, homeRefreshTick]);

  return (
    <div
      style={{ width: '100%', height: '100%', overflowY: 'auto' }}
      ref={containerRef}
      onWheel={onWheel}
    >
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', minHeight: '100%' }}>
        {articles.map((article, index) => {
          if (articles.length === index + 1 && hasMore) {
            return (
              <div ref={lastArticleRef} key={article.id}>
                <PostCard
                  id={article.id}
                  content={article.content}
                  upvotes={article.upvotes}
                  downvotes={article.downvotes}
                />
              </div>
            );
          }
          return (
            <PostCard
              key={article.id}
              id={article.id}
              content={article.content}
              upvotes={article.upvotes}
              downvotes={article.downvotes}
            />
          );
        })}
        {loading && <div>加载中...</div>}
        {!loading && !hasMore && (
          <div style={{ width: '100%', display: 'flex', alignItems: 'center', margin: '16px 0' }}>
            <div style={{ flex: 1, height: 1, backgroundColor: tokens.colorNeutralStroke2 }} />
            <div style={{ padding: '0 12px', color: tokens.colorNeutralForeground3, textAlign: 'center', whiteSpace: 'nowrap' }}>
              已经到底了喵~
            </div>
            <div style={{ flex: 1, height: 1, backgroundColor: tokens.colorNeutralStroke2 }} />
          </div>
        )}
      </div>
    </div>
  );
};

const NotFound = () => <h1>404 Not Found</h1>;

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<MainLayout />}>
          <Route index element={<Home />} />
          <Route path="create" element={<CreatePost />} />
          <Route path="about" element={<About />} />
          <Route path="*" element={<NotFound />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

export default App;
