%%-----------------------------------------------------------------------------
%% module  :       mod_glamour_ctrl
%% @author  :      zmh
%% Created :       2020-02-11
%% description:    跑马时间管理
%%-----------------------------------------------------------------------------
-module(mod_glamour_ctrl).

-include("errcode.hrl").
-include("common.hrl").
-include("def_module.hrl").
-include("predefine.hrl").
-include("glamour.hrl").

-export ([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]).
-export ([
    start_link/0
    ,gm_start/1

    ,get_act_state/1
    ,enter_close/1
    ,enter_close_run/0
    ,get_time/0
    ,activitycalen_start/1
]).

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

%%活动通知开始
activitycalen_start(_AcSub)->
    gen_server:cast(?MODULE, {activitycalen_start}).

gm_start(Time) ->
    case Time=<0 of
        true->
            gen_server:cast(?MODULE, {activitycalen_start});
        _->
            gen_server:cast(?MODULE, {gm_start,Time})
    end.

get_act_state(RoleID)->
    gen_server:cast(?MODULE,{get_act_state,RoleID}).

%%跑马主动结束
enter_close_run()->
    gen_server:cast(?MODULE,{enter_close_run}).

%%进入结束
enter_close(Reason)->
    gen_server:cast(?MODULE,{enter_close,Reason}).

get_time()->
     gen_server:call(?MODULE, {get_time}).


init([]) ->
   State = #glamour_time_mgr{},
   {ok, State}.

handle_call(Msg, From, State) ->
    case catch do_handle_call(Msg, From, State) of
        {'EXIT', Error} ->
            ?ERR("handle_call error: ~p~nMsg=~p~n", [Error, Msg]),
            {reply, error, State};
        Return  ->
            Return
    end.

handle_cast(Msg, State) ->
    case catch do_handle_cast(Msg, State) of
        {'EXIT', Error} ->
            ?ERR("handle_cast error: ~p~nMsg=~p~n", [Error, Msg]),
            {noreply, State};
        Return  ->
            Return
    end.

handle_info(Info, State) ->
    case catch do_handle_info(Info, State) of
        {'EXIT', Error} ->
            ?ERR("handle_info error: ~p~nInfo=~p~n", [Error, Info]),
            {noreply, State};
        Return  ->
            Return
    end.

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

terminate(_Reason, _State) ->
    ?ERR("~p is terminate:~p", [?MODULE, _Reason]),
    ok.

do_handle_call({get_time},_From,State)->
    #glamour_time_mgr{
        substate = SubS,
        subetime = ETime
    }=State,
    {reply,{ok,SubS,ETime},State};

do_handle_call(_Msg, _From, State) ->
    {reply, ok, State}.

%%越过idle期  直接进入准备期
do_handle_cast({gm_start,Time},State)->
    % io:format("------:~p~n",[{?MODULE,?LINE,gm}]),
    #glamour_time_mgr{ref=Ref,sub_ref=SubRef}=State,
    util:cancel_timer(Ref),
    util:cancel_timer(SubRef),
    NRef = erlang:send_after(Time*1000,self(),glamour_time),
    NState = State#glamour_time_mgr{
        state = ?STAGE_READY,
        round = 0,
        ref   = NRef,
        etime = utime:unixtime()+Time,
        substate = 0,
        sub_ref  = 0,
        subetime = 0
    },
    brocast_all_state(NState),
    {noreply,NState};

do_handle_cast({activitycalen_start},State)->
    % io:format("------:~p~n",[{?MODULE,?LINE,gm}]),
    #glamour_time_mgr{ref=Ref,sub_ref=SubRef}=State,
    util:cancel_timer(Ref),
    util:cancel_timer(SubRef),
    NRef = erlang:send_after(1000,self(),glamour_time),
    NState = State#glamour_time_mgr{
        state = ?STAGE_READY,
        round = 0,
        ref   = NRef,
        etime = utime:unixtime()+1,
        substate = 0,
        sub_ref  = 0,
        subetime = 0
    },
    brocast_all_state(NState),
    Scene = lib_guild_api:get_guild_scene(),
    mod_guild:apply_cast(lib_guild_tribe_mod,guild_act_start,[Scene,?MOD_GLAMOUR,0]),
    {noreply,NState};

do_handle_cast({get_act_state,RoleID},State)->
    #glamour_time_mgr{
        state = S,
        etime = ETime,
        substate = SubS,
        subetime = SubETime,
        round = Round
    }=State,
    {ok,Bin} = pt_142:write(14200,[S,ETime,SubS,SubETime,Round]),
    lib_server_send:send_to_uid(RoleID,Bin),
    {noreply,State};

do_handle_cast({enter_close,_Reason},State)->
    #glamour_time_mgr{ref=Ref,sub_ref=SubRef}=State,
    util:cancel_timer(Ref),
    util:cancel_timer(SubRef),
    % io:format("------:~p~n",[{?MODULE,?LINE,Reason}]),
    Now    = utime:unixtime(),
    Remain = utime:tomorrow()-Now,
    NRef   = erlang:send_after(Remain*1000,self(),enter_idle),
    Etime = Now+Remain,
    NState = State#glamour_time_mgr{state=?STAGE_CLOSE,ref=NRef,etime=Etime},
    brocast_all_state(NState),
    mod_glamour_focus:enter_account(),
    {noreply,NState};

%%根据赛程 玩家有可能提前完成赛跑 提前完成阶段
do_handle_cast({enter_close_run},State)->
    #glamour_time_mgr{
        ref=ORef,
        round=Round,
        sub_ref=OSubRef
    }=State,
    util:cancel_timer(ORef),
    util:cancel_timer(OSubRef),
    TotalR = data_glamour:get(total_round),
    ReShowT = data_glamour:get(re_show_time),
    case Round<TotalR of
        true->
            SubRef  = erlang:send_after(ReShowT*1000,self(),glamour_time),
            SubEtime = utime:unixtime()+ReShowT,
            NState = State#glamour_time_mgr{substate=?S_RESHOW,sub_ref=SubRef,subetime=SubEtime},
            brocast_all_state(NState),
            {noreply,NState};
        _->
            SubRef  = erlang:send_after(ReShowT*1000,self(),enter_close),
            SubEtime = utime:unixtime()+ReShowT,
            NState = State#glamour_time_mgr{substate=?S_RESHOW,sub_ref=SubRef,subetime=SubEtime},
            brocast_all_state(NState),
            {noreply,NState}
    end;

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

%%idle结束 进入准备
do_handle_info(enter_ready,State)->
    ReadyT = data_glamour:get(ready_time),
    Ref = erlang:send_after(ReadyT*1000,self(),glamour_time),
    Etime = utime:unixtime()+ReadyT,
    % io:format("---enter_ready---:~p~n",[{?MODULE,?LINE,utime:unixtime(),ReadyT}]),
    NState = State#glamour_time_mgr{state=?STAGE_READY,ref=Ref,etime=Etime},
    brocast_all_state(NState),
    {noreply, NState};

%%准备结束 进入活动 初次就第一场
do_handle_info(glamour_time,State) when State#glamour_time_mgr.round=<0->
    lib_chat:send_TV({all}, ?MOD_GLAMOUR, 1, []),
    %%通知战力榜单给数据
    mod_common_rank:choose_runer(),
    PreShowT = data_glamour:get(pre_show_time),
    % io:format("---glamour_time---:~p~n",[{?MODULE,?LINE,utime:unixtime(),PreShowT,1}]),
    SubRef = erlang:send_after(PreShowT*1000,self(),sub_enter_like),
    SubEtime = utime:unixtime()+PreShowT,
    NState = State#glamour_time_mgr{state=?STAGE_GLAMOUR,sub_ref=SubRef,round=1,substate=?S_PRESHOW,subetime=SubEtime},
    brocast_all_state(NState),
    mod_glamour_focus:sync_round_data(1),
    lib_chat:send_TV({all}, ?MOD_GLAMOUR, 2, [1]),
    {noreply, NState};

%%进入活动第N场
do_handle_info(glamour_time,State)->
    #glamour_time_mgr{round=CurRound}=State,
    PreShowT = data_glamour:get(pre_show_time),
    % io:format("--glamour_time---~p~n",[{?MODULE,?LINE,utime:unixtime(),PreShowT,CurRound+1}]),
    SubRef = erlang:send_after(PreShowT*1000,self(),sub_enter_like),
    SubEtime = utime:unixtime()+PreShowT,
    NState = State#glamour_time_mgr{state=?STAGE_GLAMOUR,sub_ref=SubRef,round=CurRound+1,substate=?S_PRESHOW,subetime=SubEtime},
    brocast_all_state(NState),
    mod_glamour_mgr:sync_round_data(CurRound+1),
    mod_glamour_focus:sync_round_data(CurRound+1),
    lib_chat:send_TV({all}, ?MOD_GLAMOUR, 2, [CurRound+1]),
    {noreply, NState};

%%展示结束 进入点赞阶段 大家投票
do_handle_info(sub_enter_like,State)->
    LikeT = data_glamour:get(like_time),
    % io:format("--sub_enter_like---~p~n",[{?MODULE,?LINE,utime:unixtime(),LikeT}]),
    SubRef = erlang:send_after(LikeT*1000,self(),sub_enter_run),
    SubEtime = utime:unixtime()+LikeT,
    NState = State#glamour_time_mgr{substate=?S_LIKE,sub_ref=SubRef,subetime=SubEtime},
    brocast_all_state(NState),
    {noreply,NState};

%%点赞结束 进入跑马
do_handle_info(sub_enter_run,State)->
    %%通知跑马
    RunT = data_glamour:get(run_time),
    % io:format("--sub_enter_run---:~p~n",[{?MODULE,?LINE,utime:unixtime(),RunT}]),
    SubRef = erlang:send_after(RunT*1000,self(),sub_enter_result),
    SubEtime = utime:unixtime()+RunT,
    NState = State#glamour_time_mgr{substate=?S_RUN,sub_ref=SubRef,subetime=SubEtime},
    brocast_all_state(NState),
    Scene = lib_guild_api:get_guild_scene(),
    mod_glamour_mgr:enter_run(Scene),
    mod_glamour_focus:enter_run(),
    {noreply,NState};

%%跑马结束 结算并进入结果展示
do_handle_info(sub_enter_result,State)->
    #glamour_time_mgr{round=Round}=State,
    TotalR = data_glamour:get(total_round),
    ReShowT = data_glamour:get(re_show_time),
    mod_glamour_mgr:enter_close_run(Round),
    case Round<TotalR of
        true->
            % io:format("--sub_enter_result---~p~n",[{?MODULE,?LINE,utime:unixtime(),ReShowT,Round}]),
            SubRef  = erlang:send_after(ReShowT*1000,self(),glamour_time),
            SubEtime = utime:unixtime()+ReShowT,
            NState = State#glamour_time_mgr{substate=?S_RESHOW,sub_ref=SubRef,subetime=SubEtime},
            brocast_all_state(NState),
            {noreply,NState};
        _->
            % io:format("--sub_enter_result close---~p~n",[{?MODULE,?LINE,utime:unixtime(),ReShowT,Round}]),
            SubRef  = erlang:send_after(ReShowT*1000,self(),enter_close),
            SubEtime = utime:unixtime()+ReShowT,
            NState = State#glamour_time_mgr{substate=?S_RESHOW,sub_ref=SubRef,subetime=SubEtime},
            brocast_all_state(NState),
            {noreply,NState}
    end;

%%结束 进入close
do_handle_info(enter_close,State)->
    % io:format("--enter_close---~p~n",[{?MODULE,?LINE,utime:unixtime()}]),
    Now    = utime:unixtime(),
    Remain = utime:tomorrow()-Now, %max(86400-utime:get_seconds_from_midnight(),10),
    Ref   = erlang:send_after(Remain*1000,self(),enter_idle),
    Etime = Now+Remain,
    NState = State#glamour_time_mgr{state=?STAGE_CLOSE,ref=Ref,etime=Etime},
    brocast_all_state(NState),
    mod_glamour_focus:enter_account(),
    lib_chat:send_TV({all}, ?MOD_GLAMOUR, 4, []),
    {noreply,NState};


%%close结束 进入idle
do_handle_info(enter_idle,State)->
    NState = State#glamour_time_mgr{state=?STAGE_IDLE,etime=0},
    brocast_all_state(NState),
    {noreply, NState};

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

brocast_all_state(State)->
    #glamour_time_mgr{
        state = S,
        etime = ETime,
        substate = SubS,
        subetime = SubETime,
        round = Round
    }=State,
    OpenLv = lib_module:get_open_lv(?MOD_GLAMOUR),
    {ok,Bin} = pt_142:write(14200,[S,ETime,SubS,SubETime,Round]),
    lib_server_send:send_to_all(all_lv, {OpenLv, 14200}, Bin),
    ok.


