%%%-------------------------------------------------------------------
%%% @doc    宠物-数据处理
%%% Module  : lib_pet_data.erl
%%% Created : 2019-12-09
%%% @Author : tyl
%%%-------------------------------------------------------------------
-module(lib_pet_data).
-compile(export_all).

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

-export([]).

%% -------------------------------- dict操作 -------------------------------
%% 基础培养相关
save_dict_status_pet(Player, StatusPet) ->
	NewPlayer = Player#player_status{status_pet = StatusPet},
	NewPlayer.

save_dict_pet_info(StatusPet, Pet) ->
	#status_pet{pets = PetInfoList} = StatusPet,
	NewPetInfoList = lists:keystore(Pet#pet_info.pet_id, #pet_info.pet_id, PetInfoList, Pet),
	NewStatusPet = StatusPet#status_pet{pets = NewPetInfoList},
	NewStatusPet.

update_dict_pet_info(StatusPet, Pet) ->
	#status_pet{pets = PetInfoList} = StatusPet,
	NewPetInfoList = lists:keyreplace(Pet#pet_info.pet_id, #pet_info.pet_id, PetInfoList, Pet),
	NewStatusPet = StatusPet#status_pet{pets = NewPetInfoList},
	NewStatusPet.

update_dict_follow_pet(StatusPet, PetId) ->
	#status_pet{pets = PetInfoList, follow_pet = OldFollowPet} = StatusPet,
	case OldFollowPet of
		0 ->
			PetInfo = lists:keyfind(PetId, #pet_info.pet_id, PetInfoList),
			NewPetInfoList = lists:keystore(PetId, #pet_info.pet_id, PetInfoList, PetInfo);
		_ ->
			case PetId == OldFollowPet of
				true ->
					PetInfo = lists:keyfind(PetId, #pet_info.pet_id, PetInfoList),
					NewPetInfoList = lists:keystore(PetId, #pet_info.pet_id, PetInfoList, PetInfo);
				_ ->
					PetInfo = lists:keyfind(PetId, #pet_info.pet_id, PetInfoList),
					OldFollowPetInfo = lists:keyfind(OldFollowPet, #pet_info.pet_id, PetInfoList),
					TPetInfoList   = lists:keystore(PetId, #pet_info.pet_id, PetInfoList, PetInfo),
					NewPetInfoList = lists:keystore(OldFollowPet, #pet_info.pet_id, TPetInfoList, OldFollowPetInfo)
			end
	end,
	StatusPet#status_pet{pets = NewPetInfoList}.

%% 技能石相关
update_dict_diamond_slots(Player, PetInfo, DiamondSlotInfo, ActType) ->
	#player_status{status_pet = StatusPet} = Player,
	{DiamondSlot, _DiamondId} = DiamondSlotInfo,
	#pet_info{diamond_slots = DiamondSlots} = PetInfo,
	case ActType == ?PET_DIAMOND_INLAY of
		true ->
			NewDiamondSlots = lists:keystore(DiamondSlot, 1, DiamondSlots, DiamondSlotInfo);
		_ ->
			NewDiamondSlots = lists:keydelete(DiamondSlot, 1, DiamondSlots)
	end,
	NewPetInfo   = PetInfo#pet_info{diamond_slots = NewDiamondSlots},
	NewStatusPet = update_dict_pet_info(StatusPet, NewPetInfo),
	NewPlayer    = Player#player_status{status_pet = NewStatusPet},
	NewPlayer.

%% -------------------------------- ets操作 -------------------------------
%% @doc 由于前端需要在聊天频道展示分享的宠物信息
%%      因此将宠物信息存储在ets表中，避免频繁读库
%% 保存pet数据
save_ets_pet(RoleId, Pet) ->
	case ets:lookup(?ETS_PET, RoleId) of
		[#ets_role_pets{pets = Pets}= EtsRolePets|_] ->
			NewPets = make_pets(Pets, Pet),
			NewEtsRolePets = EtsRolePets#ets_role_pets{pets = NewPets},
			ets:insert(?ETS_PET, NewEtsRolePets);
		_ ->
			ok
	end.

%% 获取pet数据
get_ets_pet(RoleId, PetId) ->
	case ets:lookup(?ETS_PET, RoleId) of
		[#ets_role_pets{pets = Pets}|_] -> skip;
		_ ->
			EtsRolePets = get_pets_from_db(RoleId),
			#ets_role_pets{pets = Pets} = EtsRolePets,
			case Pets of    %% RoleId/Pets不存在,则不更新ets表
				[] -> skip;
				_ -> ets:insert(?ETS_PET, EtsRolePets)
			end
	end,
	lists:keyfind(PetId, #ets_pet_info.pet_id, Pets).

make_pets(Pets, Pet) ->
	#pet_info{
		pet_id           = PetId
		,pet_star        = PetStar
		,pet_lv          = PetLv
		,pet_attr        = PetAttr
		,pet_power       = PetPower
		,pet_extra_power = ExtraPower
	} = Pet,
	NewEtsPetInfo =
	case lists:keyfind(PetId, #ets_pet_info.pet_id, Pets) of
		#ets_pet_info{} = EtsPetInfo ->
			EtsPetInfo#ets_pet_info{
				pet_star  = PetStar
				,pet_lv    = PetLv
				,pet_attr  = PetAttr
				,pet_power = PetPower + ExtraPower
			};
		_ ->
			#ets_pet_info{
				pet_id     = PetId
				,pet_star  = PetStar
				,pet_lv    = PetLv
				,pet_attr  = PetAttr
				,pet_power = PetPower + ExtraPower
			}
	end,
	lists:keystore(PetId, #ets_pet_info.pet_id, Pets, NewEtsPetInfo).

get_pets_from_db(RoleId) ->
	PetInfoList =
	case lib_pet_data:get_db_pets_info(RoleId) of
		[] -> [];
		InfoList ->
			lib_pet:make_list(pet, InfoList, RoleId)
	end,
	Pets = lists:foldl(fun(PetInfo, PetList) ->
							make_pets(PetList, PetInfo)
					   end, [], PetInfoList),
	#ets_role_pets{rid = RoleId, pets = Pets}.

%% -------------------------------- db操作 -------------------------------
%% 基础培养相关
get_db_pets_info(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_PET, [RoleId])).

save_db_pet_info(RoleId, PetId, PetInfo) ->
	[PetStar, PetLv, PetExp, AdoptTime, IsAwaken, OldPower] = PetInfo,
	db:execute(io_lib:format(?SQL_INSERT_PET, [RoleId, PetId, PetStar, PetLv, PetExp, AdoptTime, IsAwaken, OldPower])).

update_db_pet_info(RoleId, PetId, NewPetStar) ->
	db:execute(io_lib:format(?SQL_UPDATE_PET, [NewPetStar, RoleId, PetId])).

update_db_pet_lv(RoleId, PetId, PetLv, PetExp) ->
	db:execute(io_lib:format(?SQL_UPDATE_PET_LV, [PetLv, PetExp, RoleId, PetId])).

update_db_pet_awaken(RoleId, PetId) ->
	db:execute(io_lib:format(?SQL_UPDATE_PET_AWAKEN, [RoleId, PetId])).

update_db_pet_power(RoleId, PetId, Power) ->
	db:execute(io_lib:format(?SQL_UPDATE_PET_POWER, [Power, RoleId, PetId])).

%% 技能石相关
get_db_pet_skill_diamond(RoleId, PetId) ->
	db:get_all(io_lib:format(?SQL_SELECT_PET_SKILL_DIAMOND, [RoleId, PetId])).

save_db_pet_skill_diamond(RoleId, PetId, DiamondSlot, DiamondId) ->
	db:execute(io_lib:format(?SQL_SAVE_PET_SKILL_DIAMOND, [RoleId, PetId, DiamondSlot, DiamondId])).

%%delete_db_pet_skill_diamond(RoleId, PetId, DiamondSlot) ->
%%	Sql = io_lib:format(?SQL_DELETE_PET_SKILL_DIAMOND, [RoleId, PetId, DiamondSlot]),
%%	db:execute(Sql).

update_db_pet_skill_diamond(RoleId, PetId, DiamondSlot, DiamondId) ->
	db:execute(io_lib:format(?SQL_UPDATE_PET_SKILL_DIAMOND, [RoleId, PetId, DiamondSlot, DiamondId])).

%% 宠物支援相关
%% 玩家槽位表
get_db_pet_support(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_PET_SUPPORT_INFO, [RoleId])).

save_db_pet_support_info(RoleId, SlotId, PetId) ->
	db:execute(io_lib:format(?SQL_SAVE_PET_SUPPORT_INFO, [RoleId, SlotId, PetId, utime:unixtime()])).

update_db_pet_support_pet(RoleId, SlotId, PetId) ->
	db:execute(io_lib:format(?SQL_UPDATE_PET_SUPPORT_PET, [PetId, utime:unixtime(), RoleId, SlotId])).

update_db_pet_support_slot(RoleId, SlotId, PetId) ->
	db:execute(io_lib:format(?SQL_UPDATE_PET_SUPPORT_SLOT, [SlotId, utime:unixtime(), RoleId, PetId])).

%% 排行表
save_db_pet_support_rank(PetId, RoleId, SupportCount, OldRoleId, OldSupportCount) ->
	db:execute(io_lib:format(?SQL_SAVE_PET_SUPPORT_RANK, [PetId, RoleId, SupportCount, OldRoleId, OldSupportCount, utime:unixtime()])).

update_db_pet_support_count(RoleId, SupportCount, PetId) ->
	db:execute(io_lib:format(?SQL_UPDATE_PET_SUPPORT_COUNT, [RoleId, SupportCount, PetId])).

update_db_pet_support_rank_power(RoleId, PetId) ->
	db:execute(io_lib:format(?SQL_UPDATE_PET_SUPPORT_RANK_POWER, [RoleId, PetId])).

%% 投票表
save_db_pet_vote_info(RoleId, VoteCount, PetList, ReceiveList) ->
	PetListStr = util:term_to_string(PetList),
	ReceiveListStr = util:term_to_string(ReceiveList),
	db:execute(io_lib:format(?SQL_SAVE_PET_VOTE_INFO, [RoleId, VoteCount, PetListStr, ReceiveListStr])).

select_db_pet_vote_info(RoleId) ->
	db:get_row(io_lib:format(?SQL_SELECT_PET_VOTE_INFO, [RoleId])).

update_db_pet_vote_count(RoleId, VoteCount, PetList) ->
	PetListStr = util:term_to_string(PetList),
	db:execute(io_lib:format(?SQL_UPDATE_PET_VOTE_COUNT, [RoleId, VoteCount, PetListStr])).

update_db_pet_vote_receive_list(RoleId, ReceivePetList) ->
	ReceiveListStr = util:term_to_string(ReceivePetList),
	db:execute(io_lib:format(?SQL_UPDATE_PET_VOTE_RECEIVE_LIST, [RoleId, ReceiveListStr])).

db_get_role_power(RoleId) ->
	db:get_row(io_lib:format(<<"select `last_combat_power` from player_state where `id` = ~p">>, [RoleId])).

%% 战力榜表
save_db_pet_power_info(PetRankInfo, YestPetRankInfo) ->
	#pet_power_rank_info{
		pet_id = PetId, player_id = RoleId, pet_power = PetPower, sum_power = SumPower
	} = PetRankInfo,
	#pet_power_rank_info{
		sum_power = YestSumPower, player_id = YestRoleId
	} = YestPetRankInfo,
	db:execute(io_lib:format(?SQL_SAVE_PET_POWER_RANK, [PetId, RoleId, PetPower, SumPower, YestRoleId, YestSumPower, utime:unixtime()])).

update_db_pet_power_rank_power(RoleId, PetId) ->
	db:execute(io_lib:format(?SQL_UPDATE_PET_POWER_RANK_ROLE, [RoleId, PetId])).