%%-----------------------------------------------------------------------------
%% @Module  :       lib_supplication_api.erl
%% @Author  :       WJQ
%% @Created :       2019-04-03
%% @Description:    祈愿
%%-----------------------------------------------------------------------------
-module (lib_supplication_api).

-include ("common.hrl").
-include ("server.hrl").
-include ("supplication.hrl").
-include ("predefine.hrl").
-include ("figure.hrl").
-include ("def_event.hrl").
-include ("rec_event.hrl").

-export ([
	handle_event/2			%% 事件处理
	,daily_reset/1			%% 凌晨12点重置任务状态
	,async_trigger/2		%% 异步触发
	,sync_trigger/2			%% 同步触发
]).

%% 登录触发
handle_event(PS, #event_callback{type_id = ?EVENT_LOGIN_CAST}) when is_record(PS, player_status) ->
	{ok, NewPS} = sync_trigger(PS, {daily_login}),
	{ok, NewPS};
%% 充值触发
handle_event(PS, #event_callback{type_id = ?EVENT_RECHARGE}) when is_record(PS, player_status) ->
	{ok, NewPS} = sync_trigger(PS, {daily_charge}),
	{ok, NewPS};
%% 增加活跃度触发
handle_event(PS, #event_callback{type_id = ?EVENT_ADD_LIVENESS, data = Data}) when is_record(PS, player_status) ->
	#callback_activity_live{add_live = AddLiveness} = Data,
	{ok, NewPS} = sync_trigger(PS, {liveness, AddLiveness}),
	{ok, NewPS};
%% 离线写入未保存的数据
handle_event(PS, #event_callback{type_id = ?EVENT_DISCONNECT}) when is_record(PS, player_status) ->
	#player_status{id = RoleId, supplication = Supplication} = PS,
	#supplication{task_list = TaskList} = Supplication,
	NowTime = utime:unixtime(),
	F = fun(TaskProgress, TempList) ->
		case TaskProgress of
			#task_progress{
				task_id = TaskId, sub_type = SubType, progress = Progress, extra = Extra,
				task_status = TaskStatus, write_status = ?WSTATUS_WAIT, time = Time
			} ->
				lib_supplication:db_replace_supplication_task(RoleId, TaskId, SubType, Progress, Extra, TaskStatus, Time),
				NewTaskProgress = TaskProgress#task_progress{write_status = ?WSTATUS_SUCCESSS, write_time = NowTime},
				lists:keyreplace(TaskId, #task_progress.task_id, TempList, NewTaskProgress);
			_ ->
				TempList
		end
	end,
	NewTaskList = lists:foldl(F, TaskList, TaskList),
	NewSupplication = Supplication#supplication{task_list = NewTaskList},
	NewPS = PS#player_status{supplication = NewSupplication},
	{ok, NewPS};
handle_event(PS, _) ->
	{ok, PS}.

%% 0点清空玩家内存中的任务数据，数据库中的任务数据在重登时或触发任务时更新
%% @return {ok, #player_status{}}
daily_reset(PS) ->
	#player_status{supplication = Supplication} = PS,
	NewSupplication = Supplication#supplication{task_list = []},
	NewPS = PS#player_status{supplication = NewSupplication},
	{ok, LastPS} = sync_trigger(NewPS, {daily_login}),
	{ok, LastPS}.

%% 异步触发
%% @return ok
async_trigger(RoleId, Args) ->
	lib_player:apply_cast(RoleId, ?APPLY_CAST_SAVE, ?MODULE, sync_trigger, Args),
	ok.

%% 同步触发
%% @return {ok, #player_status{}}
sync_trigger(PS, Args) when is_record(PS, player_status) ->
	#player_status{figure = Figure} = PS,
	#figure{lv = _Lv} = Figure,
	case lib_supplication:get_act_cfg_info([reward_day, task]) of
		{ok, OpenSubType, Stime, Etime, [RewardDay, Task]} ->
			NowDay = utime:day_of_week(),
			CheckRes = check_task_args(Task, Args, []),
			if
				not is_list(RewardDay) -> %% 配置出错
					?ERR("cfg error RewardDay:~p~n", [RewardDay]),
					{ok, PS};
				true ->
					IsRewardDay = lists:member(NowDay, RewardDay),
					if
						not IsRewardDay -> %% 未到完成任务时间
							{ok, PS};
						CheckRes == [] -> %% 任务条件不符合
							{ok, PS};
						true ->
							case catch lib_supplication:trigger(PS, CheckRes, Args, OpenSubType, Stime, Etime) of
								{ok, NewPS} ->
									{ok, NewPS};
								Err ->
									?ERR("trigger error:~p~n", [Err]),
									{ok, PS}
							end
					end
			end;
		_ ->
			{ok, PS}
	end;
sync_trigger(PS, _Args) ->
	{ok, PS}.

%% 获取任务参数列表
%% @return  [{TaskId, TaskCondition},...] | []
%% TaskId 			::  integer()
%% TaskCondition	::  tuple()
%% Args 			::  tuple()
check_task_args([], _Args, CheckRes) -> CheckRes;
check_task_args([{TaskId, {daily_login}, _RewardId}|T], {daily_login}, CheckRes) ->
	NewCheckRes = [{TaskId, {daily_login}}|CheckRes],
	check_task_args(T, {login_days}, NewCheckRes);
check_task_args([{TaskId, {daily_charge}, _RewardId}|T], {daily_charge}, CheckRes) ->
	NewCheckRes = [{TaskId, {daily_charge}}|CheckRes],
	check_task_args(T, {daily_charge}, NewCheckRes);
check_task_args([{TaskId, {liveness, NeedVal}, _RewardId}|T], {liveness, AddVal}, CheckRes) ->
	NewCheckRes = [{TaskId, {liveness, NeedVal}}|CheckRes],
	check_task_args(T, {liveness, AddVal}, NewCheckRes);
check_task_args([_H|T], Args, CheckRes) ->
	check_task_args(T, Args, CheckRes);
check_task_args(_Task, _Args, CheckRes) ->
	?ERR("bad args Task:~p~n", [_Task]),
	CheckRes.