import { action } from 'typesafe-actions';

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

import { calculateMaxLevelForLeague } from 'app/utils/calculator';

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

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

export const setMaxPossibleStats = (maxStats : IMaxStats) => action(PokemonExplorerActionTypes.SET_MAX_STATS, { maxStats });

export const setLeaguePokemon = (leaguePokemon : ILeaguePokemon | null) => action(PokemonExplorerActionTypes.SET_LEAGUE_POKEMON, { leaguePokemon });

export const setIvLevel = (level : number | null) => action(PokemonExplorerActionTypes.SET_IV_LEVEL, { level });

export const setIvHp = (hp : number | null) => action(PokemonExplorerActionTypes.SET_IV_HP, { hp });

export const setIvAtk = (atk : number | null) => action(PokemonExplorerActionTypes.SET_IV_ATK, { atk });

export const setIvDef = (def : number | null) => action(PokemonExplorerActionTypes.SET_IV_DEF, { def });

export const setActiveLeague = (league : League) => action(PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE, { league });

export const fetchConfig = (
) : ThunkResult<Promise<void>> => {
    return async (dispatch, getState, extraArguments) => {
        const config = await extraArguments.services.pokemonService.getConfig();
        dispatch(setMaxPossibleStats(config.maxPossibleStats));
    };
};

export const maximizeLevel = (
) : ThunkResult<Promise<void>> => {
    return async (dispatch, getState, extraArguments) => {
        const pokemonExplorerState = getState().pokemonExplorerState;
        const {
            hp,
            atk,
            def,
        } = pokemonExplorerState.individualValues;

        if (pokemonExplorerState.leaguePokemon !== null) {
            const pokemonLeagueValues = pokemonExplorerState.leaguePokemon.pvp[pokemonExplorerState.league];
            const statsSet = pokemonLeagueValues.some((stats) => {
                if (((hp === null) || (stats.ivHp === hp)) &&
                    ((atk === null) || (stats.ivAtk === atk)) &&
                    ((def === null) || (stats.ivDef === def))
                ) {
                    dispatch(setIvHp(stats.ivHp));
                    dispatch(setIvAtk(stats.ivAtk));
                    dispatch(setIvDef(stats.ivDef));
                    dispatch(setIvLevel(stats.level));
                    return true;
                }
                return false;
            });
            if (!statsSet && hp !== null && atk !== null && def !== null) {
                dispatch(setIvLevel(calculateMaxLevelForLeague(pokemonExplorerState.leaguePokemon.stats, hp, atk, def, pokemonExplorerState.league)));
            }
        }
    };
};
