// ...existing code...
import React, { useState, useEffect, useContext, useCallback, useRef } from 'react';
import axios from 'axios';
import Container from '@mui/material/Container';
import Grid from '@mui/material/Grid';
import Pagination from '@mui/material/Pagination';
import { Link } from 'react-router-dom';
import CircularProgress from '@mui/material/CircularProgress';
import TextField from '@mui/material/TextField';
import InputAdornment from '@mui/material/InputAdornment';
import IconButton from '@mui/material/IconButton';
import SearchIcon from '@mui/icons-material/Search';
import ClearIcon from '@mui/icons-material/Clear';

import ConfigContext from './Config';
import MovieCard from './components/MovieCard';
import CategoryNav from './components/CategoryNav';
// ...existing code...

// 分类配置
const categories = [
  { label: '15min', value: '15min' },
  { label: '30min', value: '30min' },
  { label: '60min', value: '60min' },
  { label: '大于60min', value: '大于60min' },
  { label: '最新添加', value: '最新添加' },
];

const SEARCH_CATEGORY = 'search';
const LIMIT = 20;
const DEFAULT_CATEGORY = categories[0].value;

const usePersistedState = (key, defaultValue) => {
  const [state, setState] = useState(() => {
    const stored = localStorage.getItem(key);
    try {
      return stored ? JSON.parse(stored) : defaultValue;
    } catch (e) {
      console.warn(`Error parsing persisted state for key "${key}":`, e);
      return defaultValue;
    }
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(state));
  }, [key, state]);

  return [state, setState];
};

const Main = () => {
  const config = useContext(ConfigContext);

  const [loading, setLoading] = useState(true);
  const [movies, setMovies] = useState([]);
  const [pagination, setPagination] = useState({ page: 1, total: 0, pages: 1 });
  const [searchInput, setSearchInput] = useState('');

  const [activeCategory, setActiveCategory] = useState(DEFAULT_CATEGORY);
  const [currentPage, setCurrentPage] = useState(1);
  const [activeSearchQuery, setActiveSearchQuery] = useState('');

  const [persistedParams, setPersistedParams] = usePersistedState('mainViewParams', {
    lastKnownState: {
      category: DEFAULT_CATEGORY,
      page: 1,
      searchQuery: '',
      scrollPos: 0,
    },
    categoryHistory: Object.fromEntries([
      ...categories.map(cat => [cat.value, { lastPage: 1, scrollPos: 0 }]),
      [SEARCH_CATEGORY, { lastPage: 1, scrollPos: 0, searchQuery: '' }]
    ]),
  });

  const scrollTimeoutRef = useRef(null);
  const isPopStateNav = useRef(false);
  const isMounted = useRef(false);

  const fetchMovies = useCallback(async (category, page, search = '', options = {}) => {
    setLoading(true);
    try {
      const isSearch = category === SEARCH_CATEGORY;
      let apiUrl = `/movie/list?page=${page}&limit=${LIMIT}`;

      if (isSearch) apiUrl += `&search=${encodeURIComponent(search)}`;
      else if (category === '最新添加') apiUrl += `&sort=created_time&order=desc`;
      else apiUrl += `&category=${encodeURIComponent(category)}`;

      const response = await axios.get(apiUrl);
      const { items, total } = response.data.data;
      const totalPages = Math.ceil(total / LIMIT);

      if (items.length === 0 && page > 1 && !isSearch && !options.isPopState) {
        console.log("Empty page, current page has no items:", category, page);
        setMovies([]);
        setPagination({ page, total, pages: totalPages });
      } else {
        setMovies(items);
        setPagination({ page, total, pages: totalPages });
      }

    } catch (error) {
      console.error('获取电影数据失败:', error);
      setMovies([]);
      setPagination({ page, total: 0, pages: 1 });
    } finally {
      setLoading(false);
      if (options.restoreScrollPos !== undefined && !options.skipScrollRestore) {
        requestAnimationFrame(() => {
          setTimeout(() => window.scrollTo(0, options.restoreScrollPos), 50);
        });
      } else if (!options.skipScrollRestore && !options.isPopStatePaging) {
        window.scrollTo(0, 0);
      }
      isPopStateNav.current = false;
    }
    // IMPORTANT: Removed duplicated scroll logic block that was here
  }, [isPopStateNav]);

  const navigateAndFetch = useCallback((newCategory, newPage, newSearchQuery = '', options = {}) => {
    const { replace = false, preserveScroll = false, isPopStatePaging = false } = options;

    setActiveCategory(newCategory);
    setCurrentPage(newPage);
    setActiveSearchQuery(newSearchQuery);

    if (newCategory === SEARCH_CATEGORY) {
      setSearchInput(newSearchQuery);
    } else {
      setSearchInput('');
    }

    const scrollForHistory = preserveScroll
      ? (window.history.state?.appState?.scrollPos || window.scrollY)
      : 0;

    const historyState = {
      category: newCategory,
      page: newPage,
      searchQuery: newSearchQuery,
      scrollPos: scrollForHistory,
    };

    const url = window.location.pathname;
    const browserHistoryState = window.history.state?.appState;
    const needsPush = !browserHistoryState ||
      browserHistoryState.category !== newCategory ||
      browserHistoryState.page !== newPage ||
      browserHistoryState.searchQuery !== newSearchQuery;

    if (replace) {
      window.history.replaceState({ appState: historyState }, '', url);
    } else if (needsPush) {
      window.history.pushState({ appState: historyState }, '', url);
    }

    setPersistedParams(prev => {
      const newCategoryHistory = { ...prev.categoryHistory };
      const oldCategoryState = prev.lastKnownState.category;

      if (oldCategoryState && oldCategoryState !== newCategory) {
        newCategoryHistory[oldCategoryState] = {
          ...newCategoryHistory[oldCategoryState],
          scrollPos: window.scrollY,
        };
      }

      newCategoryHistory[newCategory] = {
        ...newCategoryHistory[newCategory],
        lastPage: newPage,
        scrollPos: scrollForHistory,
        ...(newCategory === SEARCH_CATEGORY && { searchQuery: newSearchQuery }),
      };

      return {
        lastKnownState: historyState,
        categoryHistory: newCategoryHistory,
      };
    });

    const scrollPosForFetch = preserveScroll ? scrollForHistory : 0;

    fetchMovies(newCategory, newPage, newSearchQuery, {
      restoreScrollPos: scrollPosForFetch,
      skipScrollRestore: false,
      isPopStatePaging: isPopStatePaging,
    });
  }, [fetchMovies, setPersistedParams]);

  useEffect(() => {
    const handlePopState = (event) => {
      if (event.state && event.state.appState) {
        const { category, page, searchQuery, scrollPos } = event.state.appState;
        isPopStateNav.current = true;

        setActiveCategory(category);
        setCurrentPage(page);
        setActiveSearchQuery(searchQuery);
        setSearchInput(searchQuery || '');

        setPersistedParams(prev => ({
          lastKnownState: event.state.appState,
          categoryHistory: {
            ...prev.categoryHistory,
            [category]: {
              ...prev.categoryHistory[category],
              lastPage: page,
              scrollPos: scrollPos,
              ...(category === SEARCH_CATEGORY && { searchQuery: searchQuery }),
            }
          }
        }));
        fetchMovies(category, page, searchQuery, { restoreScrollPos: scrollPos, isPopStatePaging: true });
      } else {
        const lastState = persistedParams.lastKnownState;
        navigateAndFetch(lastState.category, lastState.page, lastState.searchQuery, { replace: true, preserveScroll: true });
      }
    };

    window.addEventListener('popstate', handlePopState);

    if (!isMounted.current) {
      isMounted.current = true;
      if ('scrollRestoration' in window.history) {
        window.history.scrollRestoration = 'manual';
      }

      if (window.history.state && window.history.state.appState) {
        const { category, page, searchQuery, scrollPos } = window.history.state.appState;
        isPopStateNav.current = true;
        setActiveCategory(category);
        setCurrentPage(page);
        setActiveSearchQuery(searchQuery);
        setSearchInput(searchQuery || '');
        setPersistedParams(prev => ({
          lastKnownState: window.history.state.appState,
          categoryHistory: {
            ...prev.categoryHistory,
            [category]: { ...prev.categoryHistory[category], lastPage: page, scrollPos: scrollPos, ...(category === SEARCH_CATEGORY && { searchQuery: searchQuery }) }
          }
        }));
        fetchMovies(category, page, searchQuery, { restoreScrollPos: scrollPos, isPopStatePaging: true });
      } else {
        const { category, page, searchQuery } = persistedParams.lastKnownState;
        // For initial load from localStorage, use its scrollPos. navigateAndFetch with preserveScroll=true will handle it.
        navigateAndFetch(category, page, searchQuery, { replace: true, preserveScroll: true });
      }
    }

    return () => {
      window.removeEventListener('popstate', handlePopState);
      clearTimeout(scrollTimeoutRef.current);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [navigateAndFetch, setPersistedParams]);

  useEffect(() => {
    const handleScroll = () => {
      clearTimeout(scrollTimeoutRef.current);
      scrollTimeoutRef.current = setTimeout(() => {
        if (window.history.state && window.history.state.appState && !loading && movies.length > 0 && !isPopStateNav.current) {
          const newScrollPos = window.scrollY;
          const currentState = window.history.state.appState;

          if (currentState.scrollPos !== newScrollPos) {
            const updatedState = { ...currentState, scrollPos: newScrollPos };
            window.history.replaceState({ appState: updatedState }, '', window.location.href);

            setPersistedParams(prev => ({
              lastKnownState: updatedState,
              categoryHistory: {
                ...prev.categoryHistory,
                [currentState.category]: {
                  ...prev.categoryHistory[currentState.category],
                  lastPage: currentState.page,
                  scrollPos: newScrollPos,
                  ...(currentState.category === SEARCH_CATEGORY && { searchQuery: currentState.searchQuery }),
                }
              }
            }));
          }
        }
      }, 150);
    };

    if (!loading && movies.length > 0) {
      window.addEventListener('scroll', handleScroll, { passive: true });
    }
    return () => {
      window.removeEventListener('scroll', handleScroll);
      clearTimeout(scrollTimeoutRef.current);
    };
  }, [loading, movies.length, setPersistedParams, isPopStateNav, scrollTimeoutRef]);


  const handleCategoryChange = useCallback((newCategory) => {
    // Save current scroll for the category we are leaving
    setPersistedParams(prev => {
      const oldCat = prev.lastKnownState.category;
      return {
        ...prev,
        categoryHistory: {
          ...prev.categoryHistory,
          [oldCat]: { ...prev.categoryHistory[oldCat], scrollPos: window.scrollY }
        }
      };
    });

    let targetPage = 1;
    let targetSearchQuery = '';
    // For category change, restore to its own last known scroll position or top
    const categorySpecificScroll = persistedParams.categoryHistory[newCategory]?.scrollPos || 0;


    if (newCategory === SEARCH_CATEGORY) {
      targetSearchQuery = persistedParams.categoryHistory[SEARCH_CATEGORY]?.searchQuery || searchInput.trim() || '';
      targetPage = persistedParams.categoryHistory[SEARCH_CATEGORY]?.lastPage || 1;
    } else {
      targetPage = persistedParams.categoryHistory[newCategory]?.lastPage || 1;
    }

    // Update React state first
    setActiveCategory(newCategory);
    setCurrentPage(targetPage);
    setActiveSearchQuery(targetSearchQuery);
    if (newCategory === SEARCH_CATEGORY) {
      setSearchInput(targetSearchQuery);
    } else {
      setSearchInput('');
    }

    // Then fetch, telling fetchMovies to restore to the category's specific scroll
    const historyState = { category: newCategory, page: targetPage, searchQuery: targetSearchQuery, scrollPos: categorySpecificScroll };
    window.history.pushState({ appState: historyState }, '', window.location.pathname);

    setPersistedParams(prev => ({
      lastKnownState: historyState,
      categoryHistory: {
        ...prev.categoryHistory,
        [newCategory]: { ...prev.categoryHistory[newCategory], lastPage: targetPage, scrollPos: categorySpecificScroll, ...(newCategory === SEARCH_CATEGORY && { searchQuery: targetSearchQuery }) }
      }
    }));

    fetchMovies(newCategory, targetPage, targetSearchQuery, { restoreScrollPos: categorySpecificScroll });

  }, [searchInput, persistedParams.categoryHistory, setPersistedParams, fetchMovies]);


  const handlePageChange = useCallback((_, page) => {
    setPersistedParams(prev => ({
      ...prev,
      categoryHistory: {
        ...prev.categoryHistory,
        [activeCategory]: { ...prev.categoryHistory[activeCategory], scrollPos: window.scrollY }
      }
    }));
    // For page change, typically scroll to top
    navigateAndFetch(activeCategory, page, activeSearchQuery, { preserveScroll: false });
  }, [activeCategory, activeSearchQuery, navigateAndFetch, setPersistedParams]);

  const handleSearchSubmit = useCallback(() => {
    const trimmedSearch = searchInput.trim();
    if (!trimmedSearch) return;
    setPersistedParams(prev => {
      const oldCat = prev.lastKnownState.category;
      if (oldCat && oldCat !== SEARCH_CATEGORY) {
        return { ...prev, categoryHistory: { ...prev.categoryHistory, [oldCat]: { ...prev.categoryHistory[oldCat], scrollPos: window.scrollY } } };
      }
      return prev;
    });
    navigateAndFetch(SEARCH_CATEGORY, 1, trimmedSearch, { preserveScroll: false });
  }, [searchInput, navigateAndFetch, setPersistedParams]);


  const handleClearSearch = useCallback(() => {
    setSearchInput('');
    if (activeCategory === SEARCH_CATEGORY) {
      setPersistedParams(prev => ({
        ...prev,
        categoryHistory: {
          ...prev.categoryHistory,
          [SEARCH_CATEGORY]: { ...prev.categoryHistory[SEARCH_CATEGORY], scrollPos: window.scrollY, searchQuery: '', lastPage: 1 }
        }
      }));
      const targetCategory = DEFAULT_CATEGORY;
      const targetPage = persistedParams.categoryHistory[targetCategory]?.lastPage || 1;
      const targetScroll = persistedParams.categoryHistory[targetCategory]?.scrollPos || 0;

      // Manually set active states before calling fetch to avoid race with navigateAndFetch
      setActiveCategory(targetCategory);
      setCurrentPage(targetPage);
      setActiveSearchQuery('');

      const historyState = { category: targetCategory, page: targetPage, searchQuery: '', scrollPos: targetScroll };
      window.history.pushState({ appState: historyState }, '', window.location.pathname);
      setPersistedParams(prev => ({
        lastKnownState: historyState,
        categoryHistory: {
          ...prev.categoryHistory,
          [targetCategory]: { ...prev.categoryHistory[targetCategory], lastPage: targetPage, scrollPos: targetScroll }
        }
      }));
      fetchMovies(targetCategory, targetPage, '', { restoreScrollPos: targetScroll });

    } else {
      setActiveSearchQuery('');
      setPersistedParams(prev => ({ ...prev, lastKnownState: { ...prev.lastKnownState, searchQuery: '' } }));
    }
  }, [activeCategory, persistedParams.categoryHistory, setPersistedParams, fetchMovies]);


  // MODIFIED handleRename
  const handleRename = useCallback(async (oldName, newName) => {
    const scrollPosBeforeRename = window.scrollY; // 1. Capture scroll position

    try {
      const response = await axios.post('/movie/rename', { old_name: oldName, new_name: newName });
      if (response.data.code === 200) {
        // 2. await fetchMovies to ensure data is re-fetched and state is updated.
        //    Pass skipScrollRestore: true so fetchMovies doesn't scroll by itself.
        await fetchMovies(activeCategory, currentPage, activeSearchQuery, { skipScrollRestore: true });

        // 3. After movies are fetched and React has re-rendered, restore the scroll position.
        requestAnimationFrame(() => {
          window.scrollTo(0, scrollPosBeforeRename);
        });
      } else {
        throw new Error(response.data.message || '重命名失败');
      }
    } catch (error) {
      console.error('重命名错误:', error);
      throw error; // Re-throw for MovieCard to handle Snackbar
    }
  }, [fetchMovies, activeCategory, currentPage, activeSearchQuery]); // Added fetchMovies dependency

  const handleMovieCardClick = useCallback(() => {
    if (window.history.state && window.history.state.appState) {
      const currentScrollPos = window.scrollY;
      const currentState = window.history.state.appState;
      if (currentState.scrollPos !== currentScrollPos) { // Only update if changed
        const updatedState = { ...currentState, scrollPos: currentScrollPos };
        window.history.replaceState({ appState: updatedState }, '', window.location.href);
        setPersistedParams(prev => ({
          ...prev,
          lastKnownState: updatedState,
          categoryHistory: {
            ...prev.categoryHistory,
            [updatedState.category]: {
              ...prev.categoryHistory[updatedState.category],
              lastPage: updatedState.page,
              scrollPos: currentScrollPos,
              ...(updatedState.category === SEARCH_CATEGORY && { searchQuery: updatedState.searchQuery }),
            }
          }
        }));
      }
    }
  }, [setPersistedParams]);

  const handleSearchChange = (e) => setSearchInput(e.target.value);
  const handleSearchKeyDown = (e) => {
    if (e.key === 'Enter') handleSearchSubmit();
  };

  const paginationComponent = !loading && movies.length > 0 && pagination.pages > 1 && (
    <Pagination
      count={pagination.pages}
      page={currentPage}
      onChange={handlePageChange}
      sx={{ my: 2, display: 'flex', justifyContent: 'center' }}
    />
  );

  return (
    <Container style={{ marginTop: 20 }}>
      <TextField
        fullWidth
        variant="outlined"
        placeholder="搜索文件名..."
        value={searchInput}
        onChange={handleSearchChange}
        onKeyDown={handleSearchKeyDown}
        InputProps={{
          startAdornment: <InputAdornment position="start"><SearchIcon /></InputAdornment>,
          endAdornment: searchInput && (
            <InputAdornment position="end">
              <IconButton onClick={handleClearSearch} edge="end"><ClearIcon /></IconButton>
            </InputAdornment>
          )
        }}
        sx={{ mb: 2 }}
      />

      <CategoryNav
        categories={categories}
        currentCategory={activeCategory}
        onCategoryChange={handleCategoryChange}
      />

      {activeCategory === SEARCH_CATEGORY && activeSearchQuery && (
        <div style={{ textAlign: 'center', margin: '10px 0' }}>
          搜索: "{activeSearchQuery}" ({pagination.total} 个结果)
        </div>
      )}

      {paginationComponent}

      {loading && <CircularProgress sx={{ display: 'block', margin: '20px auto' }} />}

      {!loading && movies.length === 0 && (
        <div style={{ textAlign: 'center', margin: '20px 0', color: 'gray' }}>
          {activeCategory === SEARCH_CATEGORY && (searchInput || activeSearchQuery) ? `没有找到关于 "${searchInput || activeSearchQuery}" 的结果。` : '没有找到结果。'}
        </div>
      )}

      {!loading && movies.length > 0 && (
        <Grid container spacing={2} sx={{ mt: 0.5 }}>
          {movies.map(item => (
            <Grid item xs={6} sm={4} md={3} lg={2} key={item.filename}>
              <Link
                to={`/res/${item.filename}`} // Ensure your routing handles this path
                style={{ textDecoration: 'none' }}
                onClick={handleMovieCardClick}
              >
                <MovieCard movie={item} config={config} onRename={handleRename} />
              </Link>
            </Grid>
          ))}
        </Grid>
      )}

      {paginationComponent}
    </Container>
  );
};

export default Main;