Podemos hacerlo con react-native-reanimated-carousel pero lo haremos a mano porque reanimated suele tener problemas y no me quiero volver loco arreglando errores.

Vamos a HomeScreen y ponemos :

import React from 'react';

import { View, Text, ScrollView } from 'react-native';
import { useMovies } from '../../hooks/useMovies';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { PosterCarousel } from '../../componentes/movies/PosterCarousel';

export const HomeScreen = () => {
  const { isLoading, nowPlaying } = useMovies();
  const { top } = useSafeAreaInsets();
  if (isLoading) {
    return (<Text>Cargando</Text>);
  }
  return (
    <ScrollView>

      <View style={{ marginTop: top + 20, paddingBottom: 30 }} >
        <PosterCarousel movies={nowPlaying} />
      </View>

    </ScrollView>
  );
};

Ahora crearemos 2 componentes PosterCarousel y MoviePoster en el folder components con lo siguiente:

import React from 'react';
import { ScrollView, View } from 'react-native';
import { Movie } from '../../../core/entities/movie.entity';
import { MoviePoster } from './MoviePoster';

interface Props {
  movies: Movie[];
  height?: number;
}
export const PosterCarousel = ({ height = 440, movies }: Props) => {
  return (
    <View style={{ height }}>
      <ScrollView horizontal showsHorizontalScrollIndicator={false}>

        {
          movies.map(movie => <MoviePoster key={movie.id} movie={movie} />)
        }

      </ScrollView>
    </View>
  );
};

Usaremos ScrollView y no FlatList porque quiero que se rendericen todas las portadas de una vez, flat list lo haria de modo peresozo.

Ahora MoviePoster

import React from 'react';
import { Image, StyleSheet, View } from 'react-native';
import { Movie } from '../../../core/entities/movie.entity';

interface Props {
  movie: Movie;
  height?: number;
  width?: number;
}
export const MoviePoster = ({ movie, width = 300, height = 420 }: Props) => {
  return (
    <View style={{ ...styles.imageContainer, width, height }}>
      <Image style={styles.image} source={{ uri: movie.poster }} />
    </View>
  );
};


const styles = StyleSheet.create({
  image: {
    flex: 1,
    borderRadius: 18,
  },
  imageContainer: {
    flex: 1,
    borderRadius: 18,
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 10,
    },
    shadowOpacity: 0.24,
    shadowRadius: 7,
    elevation: 9,
  },
});
```

Hasta aca deberiamos poder ver las portadas.


## Navegacion entre pantallas

En `MoviePoster` con `Pressable` y `useNavigation` lograremos 
camabiar estre las pantallas de las movies.


```tsx 
import React from 'react';
import { Image, StyleSheet, View } from 'react-native';
import { Movie } from '../../../core/entities/movie.entity';
import { Pressable } from 'react-native-gesture-handler';
import { NavigationProp, useNavigation } from '@react-navigation/native';
import { RootStackParams } from '../../navigation/StackNav';

interface Props {
  movie: Movie;
  height?: number;
  width?: number;
}
export const MoviePoster = ({ movie, width = 300, height = 420 }: Props) => {
  # Typamos para obtener ayuda de las rutas disponibles
  const navigation = useNavigation<NavigationProp<RootStackParams>>();
  return (
    <Pressable
      # pasamos movieId a la pantalla details
      onPress={() => navigation.navigate('Details', { movieId: movie.id })}
      # usamos pressed para generar un efecto
      style={
        ({ pressed }) => ({
          width,
          height,
          opacity: pressed ? 0.9 : 1,
          marginHorizontal: 10,
          paddingHorizontal: 10,
          paddingBottom: 20,

        })
      }
    >
      <View style={{ ...styles.imageContainer, width, height }}>
        <Image style={styles.image} source={{ uri: movie.poster }} />
      </View>
    </Pressable>
  );
};

#algunos estilos menores
const styles = StyleSheet.create({
  image: {
    flex: 1,
    borderRadius: 18,
  },
  imageContainer: {
    flex: 1,
    borderRadius: 18,
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 10,
    },
    shadowOpacity: 0.24,
    shadowRadius: 7,
    elevation: 9,
  },
});
```

## Carousel de peliculas con FlatList 

En `HorizontalCarousel` ponemos:

```tsx 

import React from 'react';
import { View, Text } from 'react-native';
import { Movie } from '../../../core/entities/movie.entity';
import { FlatList } from 'react-native-gesture-handler';
import { MoviePoster } from './MoviePoster';
interface Props {
  movies: Movie[]
  title?: string;
}
export const HorizontalCarousel = ({ movies, title }: Props) => {
  return (
    <View
      style={{ height: title ? 260 : 220 }}
    >
      {
        title && (
          <Text
            style={{
              fontSize: 30,
              fontWeight: '300',
              marginLeft: 10,
              marginBottom: 10,
            }}
          >{title}</Text>
        )
      }
      <FlatList
        data={movies}
        renderItem={({ item }) => (
          <MoviePoster movie={item} width={140} height={200} />
        )}
        keyExtractor={item => item.id.toString()}
        horizontal={true}
        showsHorizontalScrollIndicator={false}
      />
    </View>
  );
};
```

En `HomeScreen`:


```tsx 
import React from 'react';
import { View, Text, ScrollView } from 'react-native';
import { useMovies } from '../../hooks/useMovies';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { PosterCarousel } from '../../componentes/movies/PosterCarousel';
import { HorizontalCarousel } from '../../componentes/movies/HorinzontalCarousel';

export const HomeScreen = () => {
  const { isLoading, nowPlaying, popular } = useMovies();
  const { top } = useSafeAreaInsets();
  if (isLoading) {
    return (<Text>Cargando</Text>);
  }
  return (
    <ScrollView>

      <View style={{ marginTop: top + 20, paddingBottom: 30 }} >
        <PosterCarousel movies={nowPlaying} />

        <HorizontalCarousel movies={popular} title="Populares" />
      </View>

    </ScrollView>
  );
};
```

Podemos usar `HorizontalCarousel` para las demas peliculas asi : 

```tsx 
import React from 'react';
import { View, Text, ScrollView } from 'react-native';
import { useMovies } from '../../hooks/useMovies';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { PosterCarousel } from '../../componentes/movies/PosterCarousel';
import { HorizontalCarousel } from '../../componentes/movies/HorinzontalCarousel';

export const HomeScreen = () => {
  const { isLoading, nowPlaying, popular, topRated, upcoming } = useMovies();
  const { top } = useSafeAreaInsets();
  if (isLoading) {
    return (<Text>Cargando</Text>);
  }
  return (
    <ScrollView>

      <View style={{ marginTop: top + 20, paddingBottom: 30 }} >
        <PosterCarousel movies={nowPlaying} />
        <HorizontalCarousel movies={popular} title="Populares" />
        <HorizontalCarousel movies={topRated} title="Top" />
        <HorizontalCarousel movies={upcoming} title="Upcoming" />
      </View>

    </ScrollView>
  );
};

```

## Infinite scroll Horizontal

Primero tenemos que detectar cuando es que llegamos al final

Vamos la fichero `HorizontalCarousel` y usamos la propiedad `onScroll`
esta prop tiene el `event` del cual desestructuramos los objetos de interes y haremos 
unos calculos para saber si el scroll llego al final.


```tsx
import React, { useEffect, useRef } from 'react';
import { View, Text, NativeSyntheticEvent, NativeScrollEvent } from 'react-native';
import { Movie } from '../../../core/entities/movie.entity';
import { FlatList } from 'react-native-gesture-handler';
import { MoviePoster } from './MoviePoster';
interface Props {
  movies: Movie[]
  title?: string;
  loadNextPage?: () => void;
}
const HANDICAP: number = 600;

export const HorizontalCarousel = ({ movies, title, loadNextPage }: Props) => {
  //usamos useRef porqeu no nos interesa mostrar un spinner
  //si queres poner  un loader tenes que usar useState
  const isLoading = useRef(false);

  useEffect(() => {
    setTimeout(() => {
      isLoading.current = false;
    }, 300);
  }, [movies]);

  const onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
    // Evitamos que se ejecute muchas veces la funcion si se estan
    // cargando nuevas movies
    if (isLoading.current) { return; }

    const { contentOffset, layoutMeasurement, contentSize } = event.nativeEvent;

    const isEndReached = (contentOffset.x + layoutMeasurement.width + HANDICAP) >= contentSize.width;

    if (!isEndReached) { return; }
    isLoading.current = true;
    //cargar siguientes peliculas
    loadNextPage && loadNextPage();
  };

  return (
    <View
      style={{ height: title ? 260 : 220 }}
    >
      {
        title && (
          <Text
            style={{
              fontSize: 30,
              fontWeight: '300',
              marginLeft: 10,
              marginBottom: 10,
            }}
          >{title}</Text>
        )
      }
      <FlatList
        data={movies}
        renderItem={({ item }) => (
          <MoviePoster movie={item} width={140} height={200} />
        )}
        keyExtractor={item => item.id.toString()}
        horizontal={true}
        showsHorizontalScrollIndicator={false}
        onScroll={onScroll}
      />
    </View>
  );
};
```

Hacemos uso de `useEffect` para cambiar el estado de `isLoading` , `isLoading` permite que no se dispare
multiples veces la llamda a la api si es que se esta cargando las demas peliculas.


`HomeScreen` pasa la funcion __popularNextPage__ que viene de `useMovies`

```tsx 
import React from 'react';
import { View, Text, ScrollView } from 'react-native';
import { useMovies } from '../../hooks/useMovies';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { PosterCarousel } from '../../componentes/movies/PosterCarousel';
import { HorizontalCarousel } from '../../componentes/movies/HorinzontalCarousel';

export const HomeScreen = () => {
  const { isLoading, nowPlaying, popular, topRated, upcoming, popularNextPage } = useMovies();
  const { top } = useSafeAreaInsets();
  if (isLoading) {
    return (<Text>Cargando</Text>);
  }
  return (
    <ScrollView>

      <View style={{ marginTop: top + 20, paddingBottom: 30 }} >
        <PosterCarousel movies={nowPlaying} />
        <HorizontalCarousel movies={popular} title="Populares"
          loadNextPage={popularNextPage}
        />
        <HorizontalCarousel movies={topRated} title="Top" />
        <HorizontalCarousel movies={upcoming} title="Upcoming" />
      </View>

    </ScrollView>
  );
```

El custom hook queda asi :


```tsx 
import { useEffect, useState } from 'react';
import { Movie } from '../../core/entities/movie.entity';
import * as UseCases from '../../core/use-cases/movies/';
import { movieDBFetcher } from '../../config/adapters/http/movieDB.adapter';

let popularPageNumber = 1;
export const useMovies = () => {
  const [isLoading, setIsLoading] = useState(true);
  const [nowPlaying, setNowPlaying] = useState<Movie[]>([]);
  const [popular, setPopular] = useState<Movie[]>([]);
  const [topRated, setTopRated] = useState<Movie[]>([]);
  const [upcoming, setUpcoming] = useState<Movie[]>([]);

  useEffect(() => {
    initialLoad();
  }, []);

  const initialLoad = async () => {


    const [
      nowPlayingMovies,
      upcomingMovies,
      topRatedMovies,
      popularMovies,
    ] = await Promise.all([
      UseCases.moviesNowPlayingUseCase(movieDBFetcher),
      UseCases.upcomingUseCase(movieDBFetcher),
      UseCases.topRatedUseCase(movieDBFetcher),
      UseCases.popularUseCase(movieDBFetcher),
    ]);
    setPopular(popularMovies);
    setTopRated(topRatedMovies);
    setUpcoming(upcomingMovies);
    setNowPlaying(nowPlayingMovies);

    setIsLoading(false);
  };

  return {
    isLoading,
    nowPlaying,
    popular,
    topRated,
    upcoming,
    popularNextPage: async () => {
      popularPageNumber++;
      const popularMovies = await UseCases.popularUseCase(movieDBFetcher, { page: popularPageNumber });
      setPopular(prev => [...prev, ...popularMovies]);
    },
  };
};
```

Si tenes el error de que las key estan duplicadas tenes que editar el `FlatList` de `HorizontalCarousel`
de esta manera:

```tsx 

 <FlatList
        data={movies}
        renderItem={({ item }) => (
          <MoviePoster movie={item} width={140} height={200} />
        )}
        keyExtractor={(item, index) => `${item.id.toString()}-${index}`}
        horizontal={true}
        showsHorizontalScrollIndicator={false}
        onScroll={onScroll}
      />
```

## Ver detalle de peliculas por ID

Lo primero es obtener el id de la pelicula que se obtenemos por parametro en la ruta 
`DetailsScreen` Lo cual podemos lograr de dos maneras. Con `useRoute().params` o la 
propiedad `{route}`, yo usare la propiedad route porque podemos tiparlo como veremos 
a continuacion con la linea ` interface Props extends StackScreenProps<RootStackParams, 'Details'> { }`


```tsx 
import { StackScreenProps } from '@react-navigation/stack';
import React from 'react';
import { View, Text, ScrollView } from 'react-native';
import { RootStackParams } from '../../navigation/StackNav';
import { useMovie } from '../../hooks/useMovie';
import { MovieDetails } from '../../componentes/movie/MovieDetails';
import { MovieHeader } from '../../componentes/movie/MovieHeader';
// import { useRoute } from '@react-navigation/native';

interface Props extends StackScreenProps<RootStackParams, 'Details'> { }

export const DetailsScreen = ({ route }: Props) => {
  // const {movieId} = useRoute().params
  const { movieId } = route.params;
  const { isLoading, movie, cast } = useMovie(movieId);

  if (isLoading) { return <Text>Loading</Text>; }
  return (

    <ScrollView>

      <View >
        <MovieHeader
          poster={movie?.poster!}
          originalTitle={movie?.originalTitle!}
          title={movie?.title!} />
        <MovieDetails movie={movie!} cast={cast!} />
      </View>
    </ScrollView>
  );
};
```

Lo siguiente es crear el __customHook__ que nos traiga las peliculas y el casting de actores.

```ts 
  const { isLoading, movie, cast } = useMovie(movieId);
```

```tsx 
import { useEffect, useState } from 'react';
import * as UseCase from '../../core/use-cases/';
import { movieDBFetcher } from '../../config/adapters/http/movieDB.adapter';
import { FullMovie } from '../../core/entities/movie.entity';
import { Cast } from '../../core/entities/cast.entity';
export const useMovie = (movieId: number) => {

  const [isLoading, setIsLoading] = useState(true);
  const [movie, setMovie] = useState<FullMovie | null>();
  const [cast, setCast] = useState<Cast[]>();



  useEffect(() => {
    loadMovie();
  }, [movieId]);

  const loadMovie = async () => {
    setIsLoading(true);
    try {
      const fullMoviePromise = UseCase.getMovieById(movieDBFetcher, movieId);
      const castPromise = UseCase.getMovieCastUseCase(movieDBFetcher, movieId);

      const [fullMovie, cast] = await Promise.all([fullMoviePromise, castPromise]);

      setMovie(fullMovie);
      setCast(cast);
    } catch (error) {
      console.error('Error loading movie or cast:', error);
    } finally {
      setIsLoading(false);
    }
  };


  return {
    isLoading,
    movie,
    cast,
  };

};

```

Ahora vayamos al `UseCase`

En `core/movie/` creamos dos ficheros, `get-by-id.use-case.ts` y `get-cast.use-case.ts`

en `get-by-id.use-case` pondremos :


```ts 
import { HttpAdapter } from '../../../config/adapters/http/http.adapter';
import { MovieDBMovie } from '../../../infrastructure/interfaces/movie-db.responses';
import { MovieMapper } from '../../../infrastructure/mappers/movie.mapper';
import { FullMovie } from '../../entities/movie.entity';

export const getMovieById = async (fetcher: HttpAdapter, movieId: number): Promise<FullMovie> => {

  try {
    const movie = await fetcher.get<MovieDBMovie>(`/${movieId}`);
    const fullMovie = MovieMapper.fromMovieDBToEntity(movie);
    return fullMovie;

  } catch (error) {
    throw new Error(`error fetching ${movieId}`);
  }
};
```

En este punto tenemos que crear la interface `FullMovie` que sera lo que devuelva nuestro mapper los datos 
formateados de manera que personalizaremos nosotros para no depender de la implementacion de una 
api de terceros, el `mapper` que convertira la respuesta a la api en nuestro propio objeto y la interface de  la respuesta 
del detalle de la pelicula que llamaremos `MovieDBMovie`

Comencemos con la interface, la crearemos en `core/entities/movie.entity.ts` 

```tsx
export interface Movie {
  id: number;
  title: string;
  description: string;
  releaseDate: Date;
  rating: number;
  poster: string;
  backdrop: string;
}

export interface FullMovie extends Movie {
  genres: string[];
  duration: number;
  budget: number;
  originalTitle: string;
  productionCompanies: string[]
}
```

Ya que estamos en este folder de `entities` creemos tambien `cast.entity.ts`

```ts 
export interface Cast {
  id: number;
  name: string;
  character: string;
  avatar: string;
}
```

Ahora haremos la interface de la respuesta `MovieDBMovie` en `infrastructure/interfaces/movie-db.responses.ts`
lo que deberias hacer para tener esto es ir a __postman__ y poner el id de una pelicula y copiar la respuesta
luego vas a  (https://quicktype.io)[https://quicktype.io] y generas la interface automaticamente.

Ya que estamos te dejo tambien la interfaz de __Cast__

```ts 

export interface NowPlayingResponse {
  dates: Dates;
  page: number;
  results: Result[];
  total_pages: number;
  total_results: number;
}

export interface Dates {
  maximum: Date;
  minimum: Date;
}

export interface Result {
  adult: boolean;
  backdrop_path: string;
  genre_ids: number[];
  id: number;
  original_language: string;
  original_title: string;
  overview: string;
  popularity: number;
  poster_path: string;
  release_date: Date;
  title: string;
  video: boolean;
  vote_average: number;
  vote_count: number;
}


export interface MovieDBMovie {
  adult: boolean;
  backdrop_path: string;
  belongs_to_collection: BelongsToCollection;
  budget: number;
  genres: Genre[];
  homepage: string;
  id: number;
  imdb_id: string;
  original_language: string;
  original_title: string;
  overview: string;
  popularity: number;
  poster_path: string;
  production_companies: ProductionCompany[];
  production_countries: ProductionCountry[];
  release_date: string;
  revenue: number;
  runtime: number;
  spoken_languages: SpokenLanguage[];
  status: string;
  tagline: string;
  title: string;
  video: boolean;
  vote_average: number;
  vote_count: number;
}

export interface BelongsToCollection {
  id: number;
  name: string;
  poster_path: string;
  backdrop_path: string;
}

export interface Genre {
  id: number;
  name: string;
}

export interface ProductionCompany {
  id: number;
  logo_path: null | string;
  name: string;
  origin_country: string;
}

export interface ProductionCountry {
  iso_3166_1: string;
  name: string;
}

export interface SpokenLanguage {
  english_name: string;
  iso_639_1: string;
  name: string;
}



// Generated by https://quicktype.io

export interface MovieDBCastResponse {
  id: number;
  cast: MovieDBCast[];
  crew: MovieDBCast[];
}

export interface MovieDBCast {
  adult: boolean;
  gender: number;
  id: number;
  known_for_department: string;
  name: string;
  original_name: string;
  popularity: number;
  profile_path: null | string;
  cast_id?: number;
  character?: string;
  credit_id: string;
  order?: number;
  department?: string;
  job?: string;
}
```

recuerda crear el archivo barril `index` en los casos de uso : 

```sh 
use-cases/
├── movie/
│   ├── get-by-id.use-case.ts
│   ├── get-cast.use-case.ts
│   ├── index.ts
├── movies/
│   ├── index.ts
│   ├── now-playing.use-case.ts
│   ├── popular.use-case.ts
│   ├── top-rated.use-case.ts
│   ├── upcoming.use-case.ts
│   ├── index.ts

```

en `movie` el index es este: 

```ts
export * from './get-by-id.use-case.ts';
export * from './get-cast.use-case.ts';
```
en `movies` este : 

```ts 
export * from './now-playing.use-case.ts';
export * from './upcoming.use-case.ts';
export * from './top_rated.use-case.ts';
export * from './popular.use-case.ts';
```

Nos anticiparemos al componente de `Details` y crearemos un __helper__ que nos permite 
formatear sumas de dinero, que usaremos al momento de renderizar lo que costo crear 
la  pelicula. 

Vayamos a  `src/config/helpers/formatter.ts`

```ts 
export class Formatter {
  public static currency(value: number): string {
    return new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD',
    }).format(value);
  }
}
```

Ya tenemos todo para crear los componentes  

Creemos `MovieHeader.tsx` y `MovieDetails.tsx` en `/src/presentation/components/movie/` y la misma ruta con `cast/CastActor.tsx` con los siguiente

```tsx 
import React from 'react';
import { Image, Pressable, StyleSheet, Text, View, useWindowDimensions } from 'react-native';
import { useNavigation } from '@react-navigation/native';

interface Props {
  poster: string;
  originalTitle: string;
  title: string;
}


export const MovieHeader = ({ poster, originalTitle, title }: Props) => {

  const { height: screenHeight } = useWindowDimensions();
  const navigation = useNavigation();

  return (
    <>
      <View style={{ ...styles.imageContainer, height: screenHeight * 0.7 }}>
        <View style={styles.imageBorder}>
          <Image
            style={styles.posterImage}
            source={{ uri: poster }}
          />
        </View>
      </View>

      <View style={styles.marginContainer}>
        <Text style={styles.subTitle}>{originalTitle}</Text>
        <Text style={styles.title}>{title}</Text>
      </View>

      <View style={styles.backButton}>
        <Pressable onPress={() => navigation.goBack()}>
          <Text style={styles.backButtonText}>Regresar</Text>
        </Pressable>
      </View>


    </>
  );
};


const styles = StyleSheet.create({
  imageContainer: {
    width: '100%',
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 10,
    },
    shadowOpacity: 0.24,
    shadowRadius: 7,

    elevation: 9,
    borderBottomEndRadius: 25,
    borderBottomStartRadius: 25,
  },

  imageBorder: {
    flex: 1,
    overflow: 'hidden',
    borderBottomEndRadius: 25,
    borderBottomStartRadius: 25,
  },
  posterImage: {
    flex: 1,
  },

  marginContainer: {
    marginHorizontal: 20,
    marginTop: 20,
  },
  subTitle: {
    fontSize: 16,
    opacity: 0.8,
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
  },
  backButton: {
    position: 'absolute',
    zIndex: 999,
    elevation: 9,
    top: 35,
    left: 10,
  },
  backButtonText: {
    color: 'white',
    fontSize: 25,
    fontWeight: 'bold',
    textShadowColor: 'rgba(0, 0, 0, 0.55)',
    textShadowOffset: { width: -1, height: 1 },
    textShadowRadius: 10,
  },
});
```


```tsx 

import React from 'react';
import { FlatList, View, Text } from 'react-native';
import { FullMovie } from '../../../core/entities/movie.entity';
import { Formatter } from '../../../config/helpers/formatter';
import { CastActor } from '../cast/CastActor';
import { Cast } from '../../../core/entities/cast.entity';

interface Props {
  movie: FullMovie;
  cast: Cast[];
}
export const MovieDetails = ({ movie, cast }: Props) => {
  return (
    <>
      <View style={{ marginHorizontal: 20 }}>
        <View style={{ flexDirection: 'row' }}>
          <Text>{movie.rating}</Text>

          <Text style={{ marginLeft: 5 }}>- {movie.genres.join(', ')}</Text>
        </View>

        <Text style={{ fontSize: 23, marginTop: 10, fontWeight: 'bold' }}>
          Historia
        </Text>
        <Text style={{ fontSize: 16 }}>{movie.description}</Text>

        <Text style={{ fontSize: 23, marginTop: 10, fontWeight: 'bold' }}>
          Presupuesto
        </Text>

        <Text style={{ fontSize: 18 }}>
          {Formatter.currency(movie.budget)}
        </Text>
      </View>

      {/* Casting */}
      <View style={{ marginTop: 10, marginBottom: 50 }}>
        <Text style={{
          fontSize: 23,
          marginVertical: 10,
          fontWeight: 'bold',
          marginHorizontal: 20,
        }}>
          Actores
        </Text>


        <FlatList
          data={cast}
          keyExtractor={(item) => item.id.toString()}
          horizontal
          showsHorizontalScrollIndicator={false}
          renderItem={({ item }) => <CastActor actor={item} />}
        />


      </View>
    </>


  );
};


```


```tsx 

import { Cast } from '../../../core/entities/cast.entity';

interface Props {
  actor: Cast;
}

export const CastActor = ({ actor }: Props) => {
  return (
    <View style={styles.container}>
      <Image
        source={{ uri: actor.avatar }}
        style={{ width: 100, height: 150, borderRadius: 10 }}
      />

      <View style={styles.actorInfo}>
        <Text style={{ fontSize: 15, fontWeight: 'bold' }}>{actor.name}</Text>
        <Text style={{ fontSize: 12, opacity: 0.7 }}>{actor.character}</Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    marginRight: 10,
    paddingLeft: 10,
    display: 'flex',
    flexDirection: 'column',
    width: 100,
  },
  actorInfo: {
    marginLeft: 10,
    marginTop: 4,
  },
});
```

Ahora solo tenemos que usarlos en `DetailsScreen`

```tsx 
import { StackScreenProps } from '@react-navigation/stack';
import React from 'react';
import { View, Text, ScrollView } from 'react-native';
import { RootStackParams } from '../../navigation/StackNav';
import { useMovie } from '../../hooks/useMovie';
import { MovieDetails } from '../../componentes/movie/MovieDetails';
import { MovieHeader } from '../../componentes/movie/MovieHeader';
// import { useRoute } from '@react-navigation/native';

interface Props extends StackScreenProps<RootStackParams, 'Details'> { }

export const DetailsScreen = ({ route }: Props) => {
  // const {movieId} = useRoute().params
  const { movieId } = route.params;
  const { isLoading, movie, cast } = useMovie(movieId);

  if (isLoading) { return <Text>Loading</Text>; }
  return (

    <ScrollView>

      <View >
        <MovieHeader
          poster={movie?.poster!}
          originalTitle={movie?.originalTitle!}
          title={movie?.title!} />
        <MovieDetails movie={movie!} cast={cast!} />
      </View>
    </ScrollView>
  );
};
```

Al hacer click en una pelicula tenemos que poder ver la pantalla con los detalles y un scroll 
horizontal con los actores.

## Variables de entorno


### REACT-NATIVE-DOT-ENV

[documentacion oficial](https://www.npmjs.com/package/react-native-dotenv)

1. `npm install -D react-native-dotenv`
2. Vamos a `babel.config.js` y pegamos esto:

```js
module.exports = {
  presets: ['module:@react-native/babel-preset'],
  plugins: [
    ['module:react-native-dotenv', {
      envName: 'APP_ENV',
      moduleName: '@env',
      path: '.env',
    }],
  ],
};
```

3. Nos cremos un folder en la raiz a la misma altura que `src` __NO DENTRO__ , y creaso `types/env.d.ts` 
__EL NOMBRE ES IMPORTANTE__ 

en el fichero ponemos : 

```ts 
declare module '@env' {
  export const THE_MOVIE_DB_KEY: string;
}
```

`THE_MOVIE_DB_KEY` es la Variable que tenemos en `.env`

Ya podemos usarlo, vamos a `moviedb.adapters.ts` 

```ts 
import { THE_MOVIE_DB_KEY } from '@env';
import { AxiosAdapter } from './axios.adapter';

export const movieDBFetcher = new AxiosAdapter({
  baseUrl: 'https://api.themoviedb.org/3/movie',
  params: {
    api_key: THE_MOVIE_DB_KEY ?? 'no-key',
    language: 'es',
  },
```
Luego hay q bajar la app y hacer un `--reset-cache`

```sh 
npm start -- --reset-cache
```

y todo deberia seguir funcionando.

Finalmente para terminar nuestra app, creemos un `LOADER` 

en `src/presentation/components/loader/FullScreenLoader` 

```tsx 
import { ActivityIndicator, View } from 'react-native';

export const FullScreenLoader = () => {
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignContent: 'center' }}>
      <ActivityIndicator size='large' color={ 'indigo' } />
    </View>
  )
}
```