import React, { useState, useEffect, useContext, useCallback, useReducer } 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 ConfigContext from './Config';
import MovieCard from './components/MovieCard';
import CategoryNav from './components/CategoryNav';

const initialState = {
  lastCategory: 0,
  history: {
    0: { lastPage: 1, scrollPos: 0 },
    1: { lastPage: 1, scrollPos: 0 },
    2: { lastPage: 1, scrollPos: 0 },
    3: { lastPage: 1, scrollPos: 0 },
  },
  pagination: {
    movies: [],
    page: 1,
    total: 1,
    length: 1,
  },
  loading: false,
};

function reducer(state, action) {
  switch (action.type) {
    case 'UPDATE_LAST_CATEGORY':
      return { ...state, lastCategory: action.payload.lastCategory };
    case 'UPDATE_HISTORY':
      return {
        ...state,
        history: {
          ...state.history,
          [action.payload.category]: action.payload.newData,
        },
      };
    case 'SET_PAGINATION':
      return { ...state, pagination: action.payload.pagination };
    case 'SET_LOADING':
      return { ...state, loading: action.payload.loading };
    default:
      return state;
  }
}

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

  const [state, dispatch] = useReducer(reducer, initialState);

  const updateLastCategory = useCallback((newCategory) => {
    dispatch({ type: 'UPDATE_LAST_CATEGORY', payload: { lastCategory: newCategory } });
  }, []);

  const updateHistory = useCallback((category, newData) => {
    dispatch({ type: 'UPDATE_HISTORY', payload: { category, newData } });
  }, []);

  const fetchMovies = useCallback(async (category, page) => {
    dispatch({ type: 'SET_LOADING', payload: { loading: true } });

    try {
      const response = await axios.get(
        `${config.Host}/movie/?page=${page}&limit=${config.limit}&category=${category}` // 修改这里
      );

      if (response.status === 200) {
        const data = response.data.data;

        if (data.items.length === 0 && page > 1) {
          fetchMovies(category, page - 1);
        } else {
          dispatch({
            type: 'SET_PAGINATION',
            payload: {
              pagination: {
                movies: data.items,
                page: page,
                total: data.total,
                length: Math.ceil(data.total / config.limit), // 修改这里
              },
            },
          });
        }
      }
    } catch (error) {
      console.error('Error fetching movies:', error);
    } finally {
      dispatch({ type: 'SET_LOADING', payload: { loading: false } });
    }
  }, [config.Host, config.limit]); // 修改这里

  useEffect(() => {
    const currentCategory = state.lastCategory;
    const currentPage = state.history[currentCategory].lastPage;
    fetchMovies(currentCategory, currentPage);
  }, [fetchMovies, state]);

  const handlePageChange = useCallback(
    (event, page) => {
      const currentCategory = state.lastCategory;
      updateHistory(currentCategory, { ...state.history[currentCategory], lastPage: page });
      fetchMovies(currentCategory, page);
    },
    [fetchMovies, state, updateHistory]
  );

  const handleCategoryChange = useCallback(
    (category) => {
      const currentPage = state.history[category].lastPage;
      fetchMovies(category, currentPage);

      const currentCategory = state.lastCategory;
      updateHistory(currentCategory, { ...state.history[currentCategory], scrollPos: window.scrollY });
      updateLastCategory(category);
    },
    [fetchMovies, state, updateHistory, updateLastCategory]
  );

  const handleRenderComplete = useCallback(() => {
    const { scrollPos } = state.history[state.lastCategory];
    window.scrollTo(0, scrollPos);
  }, [state]);

  const handleMovieCardClick = () => {
    const currentCategory = state.lastCategory;
    updateHistory(currentCategory, { ...state.history[currentCategory], scrollPos: window.scrollY });
  };

  return (
    <Container style={{ marginTop: 20 }}>
      <CategoryNav
        categories={config.categories} // 修改这里
        currentCategory={state.lastCategory} // 修改这里
        onCategoryChange={handleCategoryChange}
      />

      <PaginationWrapper page={state.pagination.page} length={state.pagination.length} onPageChange={handlePageChange} />

      {state.loading ? (
        <Loading />
      ) : (
        <MoviesGrid
          movies={state.pagination.movies}
          config={config}
          onRenderComplete={handleRenderComplete}
          onMovieCardClick={handleMovieCardClick}
        />
      )}

      <PaginationWrapper page={state.pagination.page} length={state.pagination.length} onPageChange={handlePageChange} />
    </Container>
  );
};

const PaginationWrapper = ({ page, length, onPageChange }) => (
  <Grid container justifyContent="center" style={{ marginTop: 20, marginBottom: 20 }}>
    <Pagination count={length} page={page} onChange={onPageChange} />
  </Grid>
);

const MoviesGrid = ({ movies, config, onRenderComplete, onMovieCardClick }) => {
  useEffect(() => {
    onRenderComplete();
  }, [movies, onRenderComplete]);

  return (
    <Grid container spacing={2} style={{ marginTop: 3 }}>
      {movies.map((item) => (
        <Grid item xs={6} sm={4} md={3} lg={2}
          style={{ display: 'flex', justifyContent: 'space-between' }}
          key={item.filename}
        >
          <Link
            to={`/res/${item.filename}`}
            style={{ textDecoration: 'none', paddingBottom: 10 }}
            onClick={onMovieCardClick}
          >
            <MovieCard movie={item} config={config} />
          </Link>
        </Grid>
      ))}
    </Grid>
  );
};

const Loading = () => (
  <Grid container justifyContent="center" style={{ marginTop: 20 }}>
    <CircularProgress />
  </Grid>
);

export default Main;