%% ---------------------------------------------------------------------------
%% @doc timer_4_clock
%% @author ming_up@foxmail.com
%% @since  2016-09-18
%% @deprecated 03:00:01执行的定时器
%% ---------------------------------------------------------------------------
-module(timer_4_clock).

-include("common.hrl").
-include("daily.hrl").
-include("def_cache.hrl").

-export([start_link/0,  handle/0]).
-export([init/1, callback_mode/0, handle_event/4, terminate/3, code_change/4]).

handle() ->
    NowTime = utime:unixtime(),
    ClsType = config:get_cls_type(),
    do_handle(ClsType),
    lib_log_api:log_server_daily_clear(?FOUR, NowTime, utime:unixtime()),
    ok.

%% 游戏服handle
do_handle(?NODE_GAME) ->
    %%% **************************************************
    %%% M:F(DelaySec) -> Res when
    %%%     DelaySec  :: integer(), DelaySec叠服延时(秒)
    %%%     Res       :: term().
    %%% Note:
    %%% 1.执行接口需要显式添加"DelaySec"叠服延时实参
    %%% 2.各执行接口添加的DelaySec，从上往下依次顺序递增
    %%% Usage:
    %%% 1.rank:award(0)
    %%% 发放排行榜奖励：即时清理榜单，延时发放奖励
    %%% **************************************************

    %% 日常清理
    OpenDay = util:get_open_day(),
    if
        OpenDay =< 1 -> %% 开服第一天就不清理日常(针对0点到4点之间开的服)
            skip;
        true ->
            mod_daily:daily_clear(?FOUR),
            lib_task:daily_clear(?FOUR, 0),
            utime:day_of_week() =:= 1 andalso mod_week:week_clear_four(),
            mod_cache:refresh(?CACHE_REFRESH_FOUR, 0),
            %% 拍卖
            %% mod_auction:daily_clear(0),
            %% 每日充值礼包
            mod_recharge_act:clear_daily_gift(30),
            %% 时装工坊刷新次数
            lib_workroom:daily_timer(),
            %% 帮派四点清理
            mod_guild:day_clear(?FOUR, 0),
            %% 玩家公会信息刷新
            lib_guild:daily_clear(?FOUR),

             %%社团劳务清理
            lib_guild_labor:daily_timer(),

            %% 资源找回
            lib_resource_back:refresh(0),
            %% 邮件推送
            %% mod_pushmail:merge_day(0),
            %% mod_pushmail:open_day(0),
            %% 定制活动
            mod_custom_act:day_trigger(?FOUR, 0),
            %% 红包
            mod_red_envelopes:daily_timer(0),
            %% 清理过期的送花记录
            lib_flower:daily_timer(10),
            %% 境界学位
            % lib_degree:daily_timer(0),
            %% 孩子日常任务
            lib_child_task:daily_clear(30),
            %%榜单4点处理
            mod_common_rank:daily_timer(?FOUR),
            %% 宠物系统
            lib_pet_api:daily_refresh(60),
            %% 孩子点赞榜排行结算
            mod_child_vote_mgr:send_vote_rank_reward(),
            %% 经验海
            exp_sea_logic:daily_refresh()
    end,
    ok;

%% 跨服handle
do_handle(?NODE_CENTER) ->
    %% 要执行的代码写在下面
    cross_point_fight_center:next_day(),
    ok;

do_handle(ClsType) ->
    ?ERR("unkown cls_type:~p", [ClsType]),
    ok.


%% 定时器启动
start_link() ->
    gen_statem:start_link({local, ?MODULE}, ?MODULE, [], []).

%%
callback_mode()->
    handle_event_function.


init([]) ->
    {_, Time} = get_next_time(),
    Ref = erlang:send_after(Time*1000, self(), 'do'),
    {ok, timeout, Ref}.

handle_event(Type, Msg, StateName, State)->
    case catch do_handle_event(Type, Msg, StateName, State) of
        {'EXIT', _R} ->
            ?ERR("handle_exit_error:~p~n", [[Type, Msg, StateName, _R]]),
            {keep_state, State};
        Reply ->
            Reply
    end.

terminate(_Reason, _StateName, _State) ->
    ok.

code_change(_OldVsn, StateName, Status, _Extra) ->
    {ok, StateName, Status}.


%% ======================================= privite function ===========================================

get_next_time() ->
    NowTime = utime:unixtime(),
    NextLogicMidnight = utime:get_next_logic_midnight(NowTime, ?DAY_LOGIC_OFFSET_HOUR),
    ExcTime = NextLogicMidnight + 1,
    {true, ExcTime - NowTime}.

do_handle_event(info, 'do', timeout, ORef)->
    util:cancel_timer(ORef),
    ?INFO("4_clock start", []),
    {IsExec, Time} = get_next_time(),
    NRef = erlang:send_after(Time*1000, self(), 'do'),
    case IsExec of
        true ->
            case catch handle() of
                ok -> skip;
                Error ->  ?ERR("handle_error:~p", [Error])
            end;
        false -> skip
    end,
    ?INFO("4_clock end is_exec =~p, next_time =~w ", [IsExec, Time]),
    {next_state, timeout, NRef};

do_handle_event(_Type, _Msg, _StateName, State) ->
    ?PRINT("no match :~p~n", [[_Type, _Msg, _StateName]]),
    {keep_state, State}.
