content: import 'package:cine_reel/bloc/bloc_provider.dart';
  import 'package:cine_reel/bloc/person_bloc.dart';
  import 'package:cine_reel/constants/api_constants.dart';
  import 'package:cine_reel/models/tmdb_movie_credits.dart';
  import 'package:cine_reel/models/tmdb_movie_details.dart';
  import 'package:cine_reel/models/tmdb_person.dart';
  import 'package:cine_reel/navigation/router.dart';
  import 'package:cine_reel/ui/common_widgets/blurred_image.dart';
  import 'package:cine_reel/ui/common_widgets/common_widgets.dart';
  import 'package:cine_reel/ui/common_widgets/errors_widget.dart';
  import 'package:cine_reel/ui/common_widgets/image_loader.dart';
  import 'package:cine_reel/ui/common_widgets/loading_widget.dart';
  import 'package:cine_reel/ui/common_widgets/poster_widget.dart';
  import 'package:cine_reel/utils/helper_functions.dart';
  import 'package:cine_reel/utils/styles.dart';
  import 'package:flutter/material.dart';
  import 'package:flutter/widgets.dart';
  
  const String MOVIE_POSTER_SIZE = SIZE_LARGE;
  
  class PersonWidget extends StatelessWidget {
    final TMDBPerson person;
    final Cast cast;
    final List<Widget> widgetsList = [];
    final bool showLoading;
    final String errorMessage;
  
    PersonWidget(
        {Key key,
        this.person,
        this.cast,
        bool this.showLoading,
        this.errorMessage})
        : super(key: key);
    final loadingWidget = LoadingWidget(
      visible: true,
    );
  
    @override
    Widget build(BuildContext context) {
      widgetsList.addAll([
        _populateBasicInfo(context),
        _populateBio(context),
        _populateFilmography(context)
      ]);
  
      if (errorMessage.isNotEmpty) {
        widgetsList.add(ErrorsWidget(
          visible: true,
          error: errorMessage,
        ));
      }
      if (showLoading) {
        widgetsList.add(loadingWidget);
      } else {
        widgetsList.remove(loadingWidget);
      }
  
      return Scaffold(
        body: DefaultTextStyle(
          child: Stack(
            children: <Widget>[
              BlurredImage(
                imageSize: SIZE_SMALL,
                imagePath: cast.profilePath,
              ),
              buildContent(),
            ],
          ),
          style: TextStyle(fontSize: 14.0),
        ),
      );
    }
  
    Widget buildContent() {
      return Column(
        children: <Widget>[
          Expanded(
            child: ListView(
              children: [
                Container(
                    margin: const EdgeInsets.only(top: 45.0),
                    padding: const EdgeInsets.symmetric(horizontal: 10.0),
                    child: Column(children: widgetsList)),
              ],
            ),
          ),
        ],
      );
    }
  
    Widget _populateBasicInfo(BuildContext context) {
      return Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          personName(),
          buildHorizontalDivider(context),
          Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              _buildProfilePicture(),
              Expanded(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    _buildIMDBLink(),
                    _populateBirthday(context),
                  ],
                ),
              ),
            ],
          ),
        ],
      );
    }
  
    Widget personName() {
      return Text(
        cast.name,
        style: STYLE_TITLE,
      );
    }
  
    Widget _buildProfilePicture() {
      return Padding(
        padding: const EdgeInsets.all(8.0),
        child: Hero(
          child: Material(
            color: Colors.transparent,
            child: _loadProfilePicture(),
          ),
          tag: "${cast.id}-${cast.name}",
        ),
      );
    }
  
    Widget _loadProfilePicture() {
      return SizedBox(
        width: 180.0,
        child: ClipRRect(
          borderRadius: BorderRadius.circular(15.0),
          child: ImageLoader(
            imagePath: cast.profilePath,
            imageType: IMAGE_TYPE.PROFILE,
            size: PROFILE_SIZES[PROFILE_SIZE],
          ),
        ),
      );
    }
  
    Widget _buildIMDBLink() {
      return CrossFadeWidgets(
          childOne: SizedBox.fromSize(
            size: Size.fromHeight(80.0),
            child: MaterialIcon("assets/imdb_icon.png", _launchIMDBUrl),
          ),
          childTwo: Container(),
          showChildOne: person != null);
    }
  
    _launchIMDBUrl() {
      var url = "$IMDB_PERSON_PAGE_BASE_URL/${person.imdbId}";
      return launchURL(url);
    }
  
    Widget _populateBio(BuildContext context) {
      return CrossFadeWidgets(
          childOne: _buildBiographyWidget(context),
          childTwo: Container(),
          showChildOne: person != null);
    }
  
    Widget _buildBiographyWidget(context) {
      bool hasBiography = person?.hasBiography() ?? false;
      if (hasBiography) {
        return Column(
          children: <Widget>[
            Text(person.biography),
            buildHorizontalDivider(context),
          ],
        );
      }
      return Container();
    }
  
    Widget _populateBirthday(BuildContext context) {
      return CrossFadeWidgets(
          childOne: _buildBirthdayWidget(context),
          childTwo: Container(),
          showChildOne: person != null);
    }
  
    Widget _buildBirthdayWidget(BuildContext context) {
      PersonBloc personBloc = BlocProvider.of<PersonBloc>(context);
  
      bool hasBirthdayDetails = person?.hasBirthdayDetails() ?? false;
  
      if (hasBirthdayDetails) {
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: <Widget>[
              buildHorizontalDivider(context),
              Row(
                children: <Widget>[
                  Expanded(
                    child: Text(personBloc.getFormattedBirthday(person),
                        style: TextStyle(
                          inherit: true,
                          fontSize: 16.0,
                        )),
                  ),
                ],
              ),
              Padding(
                padding: const EdgeInsets.only(top: 8.0, left: 8.0),
                child: Text(
                  person.getPlaceOfBirth(),
                  style: TextStyle(
                    inherit: true,
                    fontSize: 16.0,
                  ),
                ),
              ),
              buildHorizontalDivider(context),
            ],
          ),
        );
      }
      return Container();
    }
  
    Widget _populateFilmography(BuildContext context) {
      return CrossFadeWidgets(
        childOne: _buildFilmography(context),
        childTwo: Container(),
        showChildOne: person != null,
      );
    }
  
    Widget _buildFilmography(BuildContext context) {
      var filmographyHeight = MediaQuery.of(context).size.height * 0.35;
  
      bool hasMovieDetails = person?.hasMovieCredits() ?? false;
      if (hasMovieDetails) {
        var movieCredits = person.movieCredits.getFilmographyByReleaseDate();
        return SizedBox(
          height: filmographyHeight,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              _buildFilmographySubtitle(),
              _buildFilmographyList(movieCredits, filmographyHeight),
              buildHorizontalDivider(context),
            ],
          ),
        );
      }
      return Container();
    }
  
    Expanded _buildFilmographyList(
        List<MovieCreditsAsCast> movieCredits, double movieCreditHeight) {
      return Expanded(
        child: ListView.builder(
          itemCount: movieCredits.length,
          scrollDirection: Axis.horizontal,
          itemBuilder: ((BuildContext context, int index) {
            return _buildMoviePoster(
                movieCredits[index], movieCreditHeight, context);
          }),
        ),
      );
    }
  
    Padding _buildFilmographySubtitle() {
      return Padding(
        padding: const EdgeInsets.all(8.0),
        child: Text(
          "Filmography",
          style: STYLE_SUBTITLE,
        ),
      );
    }
  
    Widget _buildMoviePoster(MovieCreditsAsCast movieCredit,
        double movieCreditHeight, BuildContext context) {
      return Column(
        children: <Widget>[
          Expanded(
            child: Container(
              margin: EdgeInsets.all(3.0),
              child: SizedBox(
                height: movieCreditHeight,
                child: Material(
                  color: Colors.transparent,
                  child: InkWell(
                    onTap: () => Router.goToMovieDetailsScreen(context,
                        movieCredit.convertToTMDBMovieBasic(), MOVIE_POSTER_SIZE),
                    child: PosterWidget(
                      id: movieCredit.id,
                      imagePath: movieCredit.posterPath,
                      imageType: IMAGE_TYPE.POSTER,
                      size: MOVIE_POSTER_SIZE,
                      boxFit: BoxFit.fitWidth,
                    ),
                  ),
                ),
              ),
            ),
          ),
        ],
      );
    }
  }
  