%% ---------------------------------------------------------------------------
%% @doc mod_local_supplication.erl
%% @author WJQ
%% @since  2019-04-02
%% @deprecated 祈愿本服进程
%% ---------------------------------------------------------------------------
-module(mod_local_supplication).
-behaviour(gen_server).
-include("common.hrl").
-include("def_gen_server.hrl").
-include("supplication.hrl").
-include("def_module.hrl").
-include("custom_act.hrl").
-include("predefine.hrl").
-include("errcode.hrl").

%% API
-export([start_link/0]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-export([
	sync_broadcast/1		%% 同步广播数据
	,add_broadcast/1		%% 跨服进程通知添加一条全服祈愿记录
	,act_start/1			%% 活动开启
	,act_stop/1				%% 活动关闭
	,send_info/7			%% 发送主界面信息
	,supplication/1			%% 祈愿
	,supplication_success/1	%% 祈愿成功
]).

start_link() ->
    gen_server:start_link({local,?MODULE}, ?MODULE, [], []).

sync_broadcast(BroadcastList) ->
	gen_server:cast(?MODULE, {'sync_broadcast', BroadcastList}).

add_broadcast(Broadcast) ->
	gen_server:cast(?MODULE, {'add_broadcast', Broadcast}).

act_start(SubType) ->
	gen_server:cast(?MODULE, {'act_start', SubType}).

act_stop(SubType) ->
	gen_server:cast(?MODULE, {'act_stop', SubType}).

send_info(RoleId, SubType, ServerNum, Count, SelfLog, PackTaskList, PackRewardList) ->
	gen_server:cast(?MODULE, {'send_info', RoleId, SubType, ServerNum, Count, SelfLog, PackTaskList, PackRewardList}).

supplication(RoleId) ->
	gen_server:cast(?MODULE, {'supplication', RoleId}).

supplication_success(RewardLv) ->
	gen_server:cast(?MODULE, {'supplication_success', RewardLv}).

init(Args) ->
    ?DO_INIT(Args).
handle_call(Request, From, State) ->
    ?DO_HANDLE_CALL(Request, From, State).
handle_cast(Msg, State) ->
    ?DO_HANDLE_CAST(Msg, State).
handle_info(Info, State) ->
    ?DO_HANDLE_INFO(Info, State).
terminate(Reason, State) ->
    ?DO_TERMINATE(Reason, State).
code_change(OldVsn, State, Extra) ->
    ?DO_CODE_CHANGE(OldVsn, State, Extra).

do_init(_Args) ->
	Counter = init_supplication_counter(),
	State = #supplication_local{counter = Counter},
	Node = node_mgr:node_id(),
	clusters_node:apply_cast(mod_kf_supplication, sync_broadcast, [Node]),
    {ok, State}.

%% =================================================== CALL ===================================================
do_handle_call(_Request, _From, State) ->
    {reply, ok, State}.

%% =================================================== CAST ===================================================
%% 收到同步祈愿记录数据
do_handle_cast({'sync_broadcast', BroadcastList}, State) ->
	NewState = State#supplication_local{status = 1, broadcast_list = BroadcastList},
	{noreply, NewState};

%% 跨服进程通知添加一条全服祈愿记录
do_handle_cast({'add_broadcast', Broadcast}, State) ->
	#supplication_local{status = Status, broadcast_list = BroadcastList} = State,
	case Status == 1 of
		true -> %% 之前已同步所有记录
			case is_record(Broadcast, broadcast) of
				true ->
					TempBroadcastList = [Broadcast|BroadcastList],
					NewBroadcastList = lists:sublist(TempBroadcastList, ?SUPPLICATION_BRO_NUM),
					NewState = State#supplication_local{broadcast_list = NewBroadcastList};
				false ->
					NewState = State
			end;
		false -> %% 还没同步所有记录，先全部同步一次
			Node = node_mgr:node_id(),
			clusters_node:apply_cast(mod_kf_supplication, sync_broadcast, [Node]),
			NewState = State
	end,
	{noreply, NewState};

%% 活动开启
do_handle_cast({'act_start', _SubType}, State) ->
	case State#supplication_local.status == 1 of
		true -> skip;
		false ->
			Node = node_mgr:node_id(),
			clusters_node:apply_cast(mod_kf_supplication, sync_broadcast, [Node])
	end,
	{noreply, State};

%% 活动结束
do_handle_cast({'act_stop', _SubType}, State) ->
	%% 不清除全服祈愿记录，免得活动开启又要同步一次
	{noreply, State};

%% 发送主界面信息
do_handle_cast({'send_info', RoleId, SubType, ServerNum, Count, SelfLog, PackTaskList, PackRewardList}, State) ->
	#supplication_local{broadcast_list = BroadcastList} = State,
	PackServerLog = pack_server_log(BroadcastList),
	{ok, Bin} = pt_331:write(33196, [SubType, ServerNum, Count, PackRewardList, PackTaskList, PackServerLog, SelfLog]),
	lib_server_send:send_to_uid(RoleId, Bin),
	{noreply, State};

%% 祈愿
do_handle_cast({'supplication', RoleId}, State) ->
	#supplication_local{counter = Counter} = State,
	case lib_supplication:get_act_cfg_info([supplication_cost, guaranty, reward_limit]) of
		{ok, OpenSubType, _STime, _Etime, [Cost, {MaxCount, GuarantyLv}, RewardLimit]} ->
			lib_player:apply_cast(RoleId, ?APPLY_CAST_SAVE, lib_supplication, do_supplication, [OpenSubType, Cost, MaxCount, GuarantyLv, RewardLimit, Counter]);
		_ ->
			{ok, Bin} = pt_331:write(33199, [?ERRCODE(err331_act_closed), 0, 0, 0, 0]),
			lib_server_send:send_to_uid(RoleId, Bin)
	end,
	{noreply, State};

%% 祈愿成功
do_handle_cast({'supplication_success', RewardLv}, State) ->
	#supplication_local{counter = Counter} = State,
	UseCounter = case lists:keyfind(RewardLv, 1, Counter) of
		false -> [{RewardLv, 0, 0}|Counter];
		_ -> Counter
	end,
	case lib_supplication:get_act_cfg_info([reward_limit]) of
		{ok, _OpenSubType, _STime, _Etime, [RewardLimit]} ->
			F = fun({TRewardLv, Count, GetTimes}, TempList) ->
				case lists:keyfind(TRewardLv, 1, RewardLimit) of
					{TRewardLv, ?LIMIT_TYPE_GLOBAL, ResetCount, _RewardCount} ->
						case TRewardLv == RewardLv of
							true  -> NewGetTimes = GetTimes + 1;
							false -> NewGetTimes = GetTimes
						end,
						case Count+1 > ResetCount of
							true -> %% 达到重置次数
								delete_supplication_counter(TRewardLv),
								TempList;
							false ->
								replace_supplication_counter(TRewardLv, Count+1, NewGetTimes),
								[{TRewardLv, Count+1, NewGetTimes}|TempList]
						end;
					_ ->
						TempList
				end
			end,
			NewCounter = lists:foldl(F, [], UseCounter);
		_ ->
			F = fun({TRewardLv, Count, GetTimes}, TempList) ->
				case TRewardLv == RewardLv of
					true  -> NewGetTimes = GetTimes + 1;
					false -> NewGetTimes = GetTimes
				end,
				replace_supplication_counter(TRewardLv, Count+1, NewGetTimes),
				[{TRewardLv, Count+1, NewGetTimes}|TempList]
			end,
			NewCounter = lists:foldl(F, [], UseCounter)
	end,
	NewState = State#supplication_local{counter = NewCounter},
	{noreply, NewState};

do_handle_cast(_Msg, State) ->
    {noreply, State}.

%% =================================================== INFO ===================================================
do_handle_info(_Info, State) ->
    {noreply, State}.
do_terminate(_Reason, _State) ->
    ok.
do_code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

%% --------------------------------------------------------------------------
%%% Internal functions
%% --------------------------------------------------------------------------
pack_server_log(BroadcastList) ->
	[{RoleId, RoleName, ServerNum, RewardId} || #broadcast{role_id = RoleId, role_name = RoleName, server_num = ServerNum, reward_id = RewardId} <- BroadcastList].

%% 初始化奖励统计列表
init_supplication_counter() ->
	case get_supplication_counter() of
		[] ->
			[];
		List ->
			F = fun(Data, Acc) ->
				case Data of
					[RewardLv, Count, GetCount] ->
						[{RewardLv, Count, GetCount}|lists:keydelete(RewardLv, 1, Acc)];
					_ ->
						Acc
				end
			end,
			lists:foldl(F, [], List)
	end.

get_supplication_counter() ->
	db:get_all(?SELECT_SUPPLICATION_COUNTER).

replace_supplication_counter(RewardLv, Count, GetCount) ->
	ReSql = io_lib:format(?REPLACE_SUPPLICATION_COUNTER, [RewardLv, Count, GetCount]),
	db:execute(ReSql).

delete_supplication_counter(RewardLv) ->
	ReSql = io_lib:format(?DELETE_SUPPLICATION_COUNTER, [RewardLv]),
	db:execute(ReSql).
