%%%-------------------------------------------------------------------
%%% @doc    进阶功能调整-数据修正
%%% Module  : fix_foster.erl
%%% Created : 2021-07-09
%%% @end
%%% @author : tyl
%%%-------------------------------------------------------------------
-module(fix_foster).

-include("role_foster.hrl").
-include("def_event.hrl").
-include("goods.hrl").
-include("rec_event.hrl").
-include("server.hrl").
-include("predefine.hrl").
-include("common.hrl").

%% API
-export([
	login_fix_grade/9, db_fix_grade/0
	,login_fix_equips/2, fix_equip_after_login/2
	,fix_foster_star/3, db_fix_foster_star/0
]).

login_fix_grade(RoleId, Type, Grade, Star, Lv, Click, Clear, EndTime, Display) ->
	case Type > 4 of
		true when Grade > 0 ->
			NewGrade = 0,
			NewStar  = 0,
			NewLv = Grade * 20,
			NewClick = 0,
			NewClear = 0,
			NewEndTime = 0,
			NewDisplay = 1,
			Sql = io_lib:format(<<"update player_foster set `grade`=~p,`star`=~p,`lv`=~p,`click`=~p,`clear`=~p,`etime`=~p,`display`=~p where `rid`=~p and `type`=~p">>,
				[NewGrade, NewStar, NewLv, NewClick, NewClear, NewEndTime, NewDisplay, RoleId, Type]),
			db:execute(Sql),
			ok;
		_ ->
			NewGrade = Grade,
			NewStar  = Star,
			NewLv    = Lv,
			NewClick = Click,
			NewClear = Clear,
			NewEndTime = EndTime,
			NewDisplay = Display
	end,
	{NewGrade, NewStar, NewLv, NewClick, NewClear, NewEndTime, NewDisplay}.

db_fix_grade() ->
	GetSql = io_lib:format(<<"select `rid`, `type`, `grade` from player_foster where `type`>4">>,[]),
	case db:get_all(GetSql) of
		[_|_] = SqlInfoList ->
			F = fun(SqlInfo) ->
				case SqlInfo of
					[RoleId, Type, Grade] when Grade > 0 ->
						NewGrade = 0,
						NewStar  = 0,
						NewLv = Grade * 20,
						NewClick = 0,
						NewClear = 0,
						NewEndTime = 0,
						NewDisplayer = 0,
						Sql = io_lib:format( <<"update player_foster set `grade`=~p, `star`=~p, `lv`=~p, `click`=~p,`clear`=~p,`etime`=~p,`display`=~p where `rid`=~p and `type`=~p">>,
							[NewGrade, NewStar, NewLv, NewClick, NewClear, NewEndTime, NewDisplayer, RoleId, Type]),
						db:execute(Sql),
						ok;
					_ ->
						ignore
				end end,
			lists:map(F, SqlInfoList),
			ok;
		_ ->
			ignore
	end,
	ok.

%% #{Type=>[{grade,good_ids}...]}
login_fix_equips(RoleId, CellFosters) ->
	F = fun(CellFoster, TMap) ->
		case CellFoster of
			#cell_foster{type = Type, equips = Equips} ->
				case lists:member(Type, ?GRADE_FOSTER) of
					true -> TMap;
					_ ->
						AllGoods = lib_role_foster:get_all_equip_list(Type),
						GradeEquipList = calc_need_fix_equips(Type, Equips, AllGoods),
						case GradeEquipList =/= [] of
							true -> maps:put(Type, GradeEquipList, TMap);
							_ -> TMap
						end
				end;
			_ -> TMap
		end end,
	FixEquips = lists:foldl(F, #{}, CellFosters),
	maps:size(FixEquips) =/= 0 andalso
	lib_player_event:async_add_listener(RoleId, ?EVENT_CLIENT_LOGIN_SUCCESS, ?MODULE, fix_equip_after_login, [FixEquips]),
	ok.

%% 采用异步，延时方式处理
fix_equip_after_login(#player_status{id = RoleId} = Player, #event_callback{param = [FixEquips]}) ->
	RolePid = misc:get_player_process(RoleId),
	IsAlive = misc:is_process_alive(RolePid),
	F = fun(Type, GradeList) ->
		F1 = fun(GradeEquips) ->
			case GradeEquips of
				{Grade, EquipIds} ->
					ForFun = fun(EquipId) ->
						IsAlive andalso RolePid ! {'proto', 14607, [0, Type, Grade ,EquipId]},
						timer:sleep(20)
						end,
					lists:map(ForFun, EquipIds),
					ok;
				_ ->
					ignore
			end end,
		lists:map(F1, GradeList)
	end,
	spawn(fun() ->
			maps:map(F, FixEquips),
			lib_player_event:async_remove_listener(RoleId, ?EVENT_CLIENT_LOGIN_SUCCESS, ?MODULE, fix_equip_after_login)
			end
	),
	{ok, Player}.

calc_need_fix_equips(Type, FosterEquips, AllGoods) ->
	AllGrade = data_foster:get_all_assist_grade(Type),
	F = fun(EquipInfo, TList) ->
		case EquipInfo of
			#grade_equip{grade = Grade, equips = Equips} ->
				case lists:member(Grade, AllGrade) of
					true -> TList;
					_ ->
						EquipIds = do_calc_equips(Grade, Equips, AllGoods),
						lists:keystore(Grade, 1, TList, {Grade, EquipIds})
				end;
			_ ->
				TList
		end end,
	lists:foldl(F, [], FosterEquips).

do_calc_equips(Grade, Equips, AllGoods) ->
	F = fun(Equip, TList) ->
		case Equip of
			#foster_equip{pos = Pos} ->
				case lib_role_foster:do_get_pos_goods(Grade, Pos, AllGoods) of
					#goods{id = Uid}->
						[Uid|lists:delete(Uid, TList)];
					_ ->
						TList
				end;
			_ -> TList
		end end,
	lists:foldl(F, [], Equips).

%% 将满星修正为5星(即大于5星的都修正为5星，只需要修复开发体验)
fix_foster_star(RoleId, Type, Star) ->
	case Type =< 4 andalso ?IS_DEV_SERVER of
		true ->
			case Star > 5 of
				true ->
					NewStar = 5,
					Sql = io_lib:format(<<"update player_foster set `star`=~p where `rid`=~p and `type`=~p">>,
						[NewStar, RoleId, Type]),
					db:execute(Sql),
					ok;
				_ ->
					NewStar = Star
			end;
		_ ->
			NewStar = Star
	end,
	NewStar.

db_fix_foster_star() ->
	GetSql = io_lib:format(<<"select `rid`, `type`, `star` from player_foster where `type`<5 and `star`>5">>,[]),
	case db:get_all(GetSql) of
		[_|_] = SqlInfoList ->
			F = fun(SqlInfo) ->
				case SqlInfo of
					[RoleId, Type, Star] when Star > 5 ->
						NewStar = 5,
						Sql = io_lib:format(<<"update player_foster set `star`=~p where `rid`=~p and `type`=~p">>,
							[NewStar, RoleId, Type]),
						db:execute(Sql),
						ok;
					_ ->
						ignore
				end end,
			lists:map(F, SqlInfoList);
		_ ->
			ignore
	end.
