%%%-------------------------------------------------------------------
%%% @doc    宠物-检查
%%% Module  : lib_pet_check.erl
%%% Created : 2019-12-09
%%% @Author : tyl
%%%-------------------------------------------------------------------
-module(lib_pet_check).

-include("common.hrl").
-include("server.hrl").
-include("pet.hrl").
-include("errcode.hrl").

-export([
	check_active/2                 %% 宠物激活检查
	,check_upgrade/1               %% 宠物进化检查
	,check_grow_up/1               %% 宠物喂养检查
	,check_diamond_inlay/1         %% 技能宝石镶嵌检查
	,check_normal_support_pet/1    %% 宠物普通支援检查
	,check_support_pet/1           %% 宠物上阵检查
]).

check_active([], Player) -> {true, Player};
check_active([Check|L], Player) ->
	case do_check_active(Check, Player) of
		{true, NewPlayer} -> check_active(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

check_upgrade([]) -> true;
check_upgrade([Check|L]) ->
	case do_check_upgrade(Check) of
		true -> check_upgrade(L);
		{false, Res} -> {false, Res}
	end.

check_grow_up([]) -> true;
check_grow_up([Check|L]) ->
	case do_check_grow_up(Check) of
		true -> check_grow_up(L);
		{false, Res} -> {false, Res}
	end.

check_diamond_inlay([]) -> true;
check_diamond_inlay([Check|L]) ->
	case do_check_diamond_inlay(Check) of
		true -> check_diamond_inlay(L);
		{false, Res} -> {false, Res}
	end.

check_normal_support_pet([]) -> true;
check_normal_support_pet([Check|L]) ->
	case do_check_normal_support_pet(Check) of
		true -> check_normal_support_pet(L);
		{false, Res} -> {false, Res}
	end.

check_support_pet([]) -> true;
check_support_pet([Check|L]) ->
	case do_check_support_pet(Check) of
		true -> check_support_pet(L);
		{false, Res} -> {false, Res}
	end.

do_check_active({has_actived, PetId}, Player) ->
	#player_status{status_pet = StatusPet} = Player,
	#status_pet{pets = PetInfoList} = StatusPet,
	case lists:keyfind(PetId, #pet_info.pet_id, PetInfoList) of
		#pet_info{} -> {false, ?ERRCODE(err163_already_adopt), Player};
		_ -> {true, Player}
	end;
do_check_active({enough_debris, GoodsId, Num}, Player) ->
	[{_, OwnNum}] = lib_goods_api:get_goods_num(Player, [GoodsId]),
	case OwnNum >= Num of
		true -> {true, Player};
		_ -> {false, ?ERRCODE(err163_debris_not_enough), Player}
	end;
do_check_active(_Check, Player) ->
	?ERR("<<Error check_active>>"),
	{false, ?FAIL, Player}.

do_check_upgrade({is_max_star, PetId, PetStar}) ->
	NextStar = lib_pet:calc_next_star(PetId, PetStar),
	if
		NextStar =:= 0 -> {false, ?ERRCODE(err163_pet_max_stage)};
		true -> true
	end;
do_check_upgrade({enough_debris, PetId, PetStar}) ->
	NextStar = lib_pet:calc_next_star(PetId, PetStar),
	case NextStar =:= 0 of
		true -> {false, ?ERRCODE(err163_pet_max_stage)};
		_ ->
			case data_pet:get_pet_cfg(PetId, NextStar) of
				#pet_cfg{cost = [{_Type, GoodsId, Num}]} ->
					[{_, OwnNum}] = lib_goods_api:get_goods_num(none, [GoodsId]),
					case OwnNum >= Num of
						true -> true;
						_ -> {false, ?ERRCODE(err163_debris_not_enough)}
					end;
				_ -> {false, ?ERRCODE(err163_pet_max_stage)}
			end
	end;
do_check_upgrade(_Check) ->
	?ERR("<<Error check_upgrade>>"),
	{false, ?FAIL}.

do_check_grow_up({max_lv, RareDegree, PetLv}) ->
	case data_pet:get_pet_grow_up_cfg(RareDegree, PetLv+1) of
		#pet_grow_up_cfg{} -> true;
		_ -> {false, ?ERRCODE(err163_is_max_lv)}
	end;
do_check_grow_up({goods_enough, GoodsId, GoodsList}) ->
	case lists:keyfind(GoodsId, 1, GoodsList) of
		{_GoodsId, _AddExp} ->
			[{_, OwnNum}] = lib_goods_api:get_goods_num(none, [GoodsId]),
			case OwnNum >= 1 of
				true -> true;
				_ -> {false, ?ERRCODE(err163_debris_not_enough)}
			end;
		_ -> {false, ?ERRCODE(err163_not_grow_up_matrial)}
	end;
do_check_grow_up(_Check) ->
	?ERR("<<Error check_grow_up>>"),
	{false, ?FAIL}.

do_check_diamond_inlay({has_diamond, DiamondId}) ->
	[{_, OwnNum}] = lib_goods_api:get_goods_num(none, [DiamondId]),
	case OwnNum >= 1 of
		true -> true;
		_ -> {false, ?ERRCODE(err163_no_diamond)}
	end;
do_check_diamond_inlay({diamond_slot, DiamondSlot}) ->
	case lists:member(DiamondSlot, ?SKILL_DIAMOND_SLOT_LIST) of
		true -> true;
		_ -> {false, ?ERRCODE(err163_not_diamond_slot)}
	end;
do_check_diamond_inlay({is_need_race, DiamondId, PetId}) ->
	case data_pet:get_pet_cfg(PetId, 1) of
		#pet_cfg{pet_race = Race} ->
			case data_pet:get_pet_diamond_storage_cfg(DiamondId) of
				#pet_diamond_storage_cfg{need_race = NRace} when Race == NRace ->
					true;
				_ -> {false, ?ERRCODE(err163_not_pet_race)}
			end;
		_ ->
			?ERR("<<pet cfg err!>>"),
			{false, ?ERRCODE(err163_pet_cfg_err)}
	end;
do_check_diamond_inlay({is_same_diamond, DiamondId, DiamondSlots}) ->
	DiamondList = [DiamondId||{_TDiamondSlot, TDiamondId}<- DiamondSlots, DiamondId == TDiamondId],
	case DiamondList of
		[] -> true;
		_ -> {false, ?ERRCODE(err163_diamond_has_inlay)}
	end;
do_check_diamond_inlay(_Check) ->
	?ERR("<<Error check_diamond_inlay>>"),
	{false, ?FAIL}.

do_check_normal_support_pet({has_adopt_pet, PetInfoList, PetId}) ->
	case lists:keyfind(PetId, #pet_info.pet_id, PetInfoList) of
		#pet_info{} -> true;
		_ -> {false, ?ERRCODE(err163_not_adopt)}
	end;
do_check_normal_support_pet({is_slot_open, OpenSlots, SlotId}) ->
	case lists:member(SlotId, OpenSlots) of
		true -> true;
		_ -> {false, ?ERRCODE(err163_slot_not_active)}
	end;
do_check_normal_support_pet({is_same_slot, SupportList, SlotId, PetId}) ->
	case lists:keyfind(SlotId, #pet_support_slot.slot_id, SupportList) of
		#pet_support_slot{pet_id = PetId} -> {false, ?ERRCODE(err163_not_need_support_again)};
		_ -> true
	end;
do_check_normal_support_pet(_Check) ->
	?ERR("<<Error check_normal_support_pet>>"),
	{false, ?FAIL}.

do_check_support_pet({has_adopt_pet, PetId, PetList}) ->
	case PetList of
		[_|_] ->
			case lists:keyfind(PetId, #pet_info.pet_id, PetList) of
				#pet_info{} -> true;
				_ -> {false, ?ERRCODE(err163_not_adopt)}
			end;
		_ -> {false, ?ERRCODE(err163_not_adopt)}
	end;
do_check_support_pet({slot_id, SlotId, SlotList}) ->
	case lists:member(SlotId, SlotList) of
		true -> true;
		_ -> {false, ?FAIL}
	end;
do_check_support_pet({pet_id, PetId, AllPets}) ->
	case lists:member(PetId, AllPets) of
		true -> true;
		_ -> {false, ?FAIL}
	end;
do_check_support_pet({is_same_pet, SupportList, SlotId, PetId}) ->
	case lists:keyfind(SlotId, #pet_support_slot.slot_id, SupportList) of
		#pet_support_slot{pet_id = TPetId} ->
			if PetId == TPetId ->
				{false, ?ERRCODE(err163_pet_cannot_support_again)};
				true -> true
			end;
		_ -> true
	end;
do_check_support_pet(_Check) ->
	?ERR("<<Error check_server_support_pet>>"),
	{false, ?FAIL}.