text: import React, { Component } from "react";
  import Pagination from "./common/pagination";
  import { getMovies } from "../services/fakeMovieService";
  import { getGenres } from "../services/fakeGenreService";
  import { paginate } from "../utils/paginate";
  import ListGroup from "./common/listGroup";
  import MoviesTable from "./moviesTable";
  import _ from "lodash";
  
  class Movies extends Component {
    state = {
      /*the reason why we initialize the movies and genres as empty arrays is because
      it takes time until we get data from back end server, 
      and during this time, we don't want the movies and genres become undefined */
      movies: [],
      genres: [],
      currentPage: 1,
      pageSize: 4,
      sortColumn: { path: "title", order: "asc" }
    };
  
    componentDidMount() {
      const genres = [{ name: "All Genres" }, ...getGenres()];
      this.setState({ movies: getMovies(), genres: genres });
    }
  
    handleDelete = movie => {
      // const movies = this.state.movies.filter(m => m._id !== movie._id);
  
      //call the .slice(), the original array automatically changed
      const index = this.state.movies.indexOf(movie);
      this.state.movies.splice(index, 1);
      const movies = this.state.movies;
      this.setState({ movies });
    };
  
    handleLike = movie => {
      const movies = [...this.state.movies];
      const index = movies.indexOf(movie);
      movies[index] = { ...movies[index] };
      movies[index].liked = !movies[index].liked;
      this.setState({ movies });
    };
  
    handlePageChange = page => {
      this.setState({ currentPage: page });
    };
  
    handleGenreSelect = genre => {
      this.setState({ selectedGenre: genre, currentPage: 1 });
    };
  
    handleSort = sortColumn => {
      this.setState({ sortColumn });
    };
  
    getPageData = () => {
      const {
        pageSize,
        currentPage,
        sortColumn,
        movies: allMovies,
        selectedGenre
      } = this.state;
  
      const filtered =
        selectedGenre && selectedGenre._id
          ? allMovies.filter(m => m.genre._id === selectedGenre._id)
          : allMovies;
  
      //there are several paths and several orders, so they are array
      const sorted = _.orderBy(filtered, [sortColumn.path], [sortColumn.order]);
  
      const movies = paginate(sorted, currentPage, pageSize);
      return { totalCount: filtered.length, data: movies };
    };
  
    render() {
      const { length: count } = this.state.movies;
      const {
        pageSize,
        currentPage,
        sortColumn,
        genres,
        selectedGenre
      } = this.state;
  
      if (count === 0) return <p>There are no movies in the database.</p>;
  
      const { totalCount, data: movies } = this.getPageData();
  
      return (
        <div className="row">
          <div className="col-3">
            <ListGroup
              items={genres}
              selectedItem={selectedGenre}
              onItemSelect={this.handleGenreSelect}
              onAllItem={this.handleAllItem}
            />
          </div>
          <div className="col">
            {/*here must use filtered instead of movies, because movies 
            only represents the current page movies, but filtered represents 
            all movies in given selection */}
            <p>Showing {totalCount} movies in the database.</p>
            <MoviesTable
              movies={movies}
              onLike={this.handleLike}
              onDelete={this.handleDelete}
              onSort={this.handleSort}
              sortColumn={sortColumn}
            />
            <Pagination
              itemCount={totalCount}
              pageSize={pageSize}
              currentPage={currentPage}
              onPageChange={this.handlePageChange}
            />
          </div>
        </div>
      );
    }
  }
  
  export default Movies;
  