import POGOProtos from 'pogo-protos';

import { action } from 'typesafe-actions';

import { ILeaguePokemon } from 'app/models/League';
import { IPokemon } from 'app/models/Pokemon';

import { ThunkResult } from 'app/types';
import { PokemonSelectListActionTypes } from './types';

export const setIsLoading = (isLoading : boolean) => action(PokemonSelectListActionTypes.SET_IS_LOADING, { isLoading });

export const setPokemonList = (pokemonList : Array<IPokemon>) => action(PokemonSelectListActionTypes.SET_POKEMON_LIST, { pokemonList });

export const setPokemonListFiltered = (filterTerm : string, pokemonListFiltered : Array<IPokemon>) => action(PokemonSelectListActionTypes.SET_POKEMON_LIST_FILTERED, { filterTerm, pokemonListFiltered });

export const setActivePokemonId = (activePokemonId : POGOProtos.Enums.PokemonId | null, activePokemonForm : POGOProtos.Enums.Form | null) => action(PokemonSelectListActionTypes.SET_ACTIVE_POKEMON_ID, { activePokemonId, activePokemonForm });

export const setPokemonLeagueStats = (pokemonId : POGOProtos.Enums.PokemonId, pokemonLeagueStats : ILeaguePokemon) => action(PokemonSelectListActionTypes.SET_POKEMON_LEAGUE_STATS, { pokemonId, pokemonLeagueStats });

export const filterPokemonList = (
    filterTerm : string
) : ThunkResult<Promise<void>> => {
    return async (dispatch, getState, extraArguments) => {
        let pokemonListFiltered : Array<IPokemon> = [];
        if (filterTerm !== '') {
            const pokemonList = getState().pokemonSelectListState.pokemonList;
            const normalizedFilterTerm = filterTerm.toLowerCase();
            pokemonListFiltered = pokemonList.reduce((result : Array<IPokemon>, pokemon) => {
                const pokemonName = pokemon.name.toLowerCase();
                const pokemonDex = '' + pokemon.dex;
                const pokemonForm = pokemon.form === null ? '' : POGOProtos.Enums.Form[pokemon.form].toLowerCase();
                if (pokemonName.indexOf(normalizedFilterTerm) === 0 ||
                    pokemonDex.indexOf(normalizedFilterTerm) === 0 ||
                    normalizedFilterTerm === pokemonForm
                ) {
                    result.push(pokemon);
                }
                return result;
            }, []);
        }
        dispatch(setPokemonListFiltered(filterTerm, pokemonListFiltered));
    };
};

export const fetchPokemonList = (
) : ThunkResult<Promise<void>> => {
    return async (dispatch, getState, extraArguments) => {
        const pokemonList = await extraArguments.services.pokemonService.getPokemonList();
        dispatch(setPokemonList(pokemonList));
    };
};

export const fetchPokemonLeagueStats = (
    pokemonId : POGOProtos.Enums.PokemonId,
    form : POGOProtos.Enums.Form
) : ThunkResult<Promise<ILeaguePokemon>> => {
    return async (dispatch, getState, extraArguments) => {
        const pokemonLeagueStats = await extraArguments.services.pokemonService.getPokemonLeagueStats(pokemonId, form);
        dispatch(setPokemonLeagueStats(pokemonId, pokemonLeagueStats));
        return pokemonLeagueStats;
    };
};
