%% ---------------------------------------------------------------------------
%% @doc mod_dungeon_info.erl

%% @author  hjh
%% @email  hejiahua@163.com
%% @since  2017-02-14
%% @deprecated 副本进程
%% ---------------------------------------------------------------------------
-module(mod_dungeon_info).
-export([handle_info/2]).

-include("dungeon.hrl").
-include("common.hrl").
-include("predefine.hrl").
-include("scene.hrl").
-include ("errcode.hrl").

-spec handle_info(Msg, State) -> 
    {noreply, State}
    | {stop, Reason, State} when
    Msg :: term(),
    Reason :: term(),
    State :: #dungeon_state{}.
handle_info(Msg, State) ->
    case catch do_handle_info(Msg, State) of
        {noreply, NewState} ->
            {noreply, NewState};
        NewState = #dungeon_state{} ->
            {noreply, NewState};
        Val when Val == ok orelse Val == skip ->
            {noreply, State};
        {stop, _Reason, State} ->
            _Reason =/= normal andalso ?ERR("dun handle info msg ~p ~n stop reason ~p ", [Msg, _Reason]),
            {stop, normal, State};
        _Reason ->
            ?ERR("dun handle info msg ~p ~n error reason ~p", [Msg, _Reason]),
            {noreply, State}
    end.

do_handle_info({'create_dun_wave_mon', Wave, MonList}, State) ->
    NewState = lib_dungeon_distribute:create_mon(State, Wave, MonList),
    {noreply, NewState};

%% 加载场景超时,直接开始,不设置特效定时了
do_handle_info({'create_init_dun_wave_mon', LoadSign, _Wave, _MonList}, State) ->
    %% 副本开始
    NewState0 = dungeon_logic:refresh_init_wave_info(State),
    % 设置评分事件
    StateAfScore = lib_dungeon_distribute:make_grade_event(NewState0),
    % 副本通用评级
    StateAfRating = lib_dungeon_distribute:make_grade_rating(StateAfScore),
    NewState  = StateAfRating#dungeon_state{init_wave_sign = LoadSign},
    {noreply, NewState};

%% 特效播放超时
do_handle_info({animation_timeout}, State) ->
    % ?ERR("animation_timeout", []),
    %% 副本开始了
    NewState0    = dungeon_logic:refresh_init_wave_info(State),
    % 设置评分事件
    StateAfScore = lib_dungeon_distribute:make_grade_event(NewState0),
    % 副本通用评级
    StateAfRating = lib_dungeon_distribute:make_grade_rating(StateAfScore),
    #dungeon_state{scene_id = SceneId, dun_id = DunId, wave_num = WaveNum, role_list = RoleList} = NewState = StateAfRating#dungeon_state{init_wave_sign = ?INIT_WAVE_LOAD_SIGN},
    {DunStart, DunEnd, WaveStart, WaveEnd} = dungeon_logic:get_dun_time_info(NewState),
    {ok, BinData} = pt_611:write(61124, [SceneId, DunId, DunStart, DunEnd, WaveNum, WaveStart, WaveEnd, ?SUCCESS]),
    dungeon_logic:notice_dun_role_info(RoleList, BinData),
    {noreply, NewState};    

%% 副本评分事件检查
do_handle_info({trigger_time_pass_check, Type, RoleId, ConfigIndex, PassTime}, State) ->
    if Type == dun_grade ->
            NewState = dungeon_logic:update_time_pass_score(RoleId, ConfigIndex, PassTime, State);
        true ->
            NewState = dungeon_logic:update_dun_rating(RoleId, ConfigIndex, PassTime, State)
    end,
    {noreply, NewState};

%% 副本结束
do_handle_info({'dungeon_timeout'}, State) ->
    NewState = dungeon_logic:dungeon_timeout(State),
    {noreply, NewState};

%% 波数超时
do_handle_info({'wave_timeout', DunId, Wave, WaveIndex}, State) ->
    NewState = dungeon_logic:wave_timeout(DunId, Wave, WaveIndex, State),
    {noreply, NewState};

%% 强制退出定时器 副本里没人直接关闭
do_handle_info({'force_quit_ref'}, #dungeon_state{role_list = []} = State) ->
    {stop, normal, State};

%% 强制退出定时器
do_handle_info({'force_quit_ref'}, State) ->
    #dungeon_state{result_type = ResultType, result_subtype = ResultSubType, force_quit_ref = ForceQuitRef, role_list = RoleList} = State,
    util:cancel_timer(ForceQuitRef),
    F = fun(#dungeon_role{id = RoleId, is_end_out = IsEndOut, online = OL}, TmpState) ->
        IsOnline = OL =:= ?DUN_ONLINE_YES orelse OL =:= ?DUN_ONLINE_DELAY,
        case IsEndOut == ?DUN_IS_END_OUT_NO orelse IsOnline of
            true -> 
                lib_dungeon_distribute:handle_role_out(RoleId, ?DUN_LOG_TYPE_ROLE_OUT, ResultType, ResultSubType, TmpState);
            false ->
                TmpState
        end
    end,
    State1 = lists:foldl(F, State, RoleList),
    dungeon_default:check_all_dun_role_out(State1#dungeon_state.role_list, ForceQuitRef),
    {noreply, State1};

%% 复活定时器
do_handle_info({'revive_ref', RoleId}, State) ->
    #dungeon_state{role_list = RoleList} = State,
    case lists:keyfind(RoleId, #dungeon_role.id, RoleList) of
        false -> NewState = State;
        #dungeon_role{hp_lim = HpLim, revive_ref = OldRef, node = Node} = DungeonRole ->
            util:cancel_timer(OldRef),
            lib_player:apply_cast(Node, RoleId, ?APPLY_CAST_SAVE, ?NOT_HAND_OFFLINE, lib_revive, revive_without_check, [?REVIVE_DUNGEON, []]),
            NewDungeonRole = DungeonRole#dungeon_role{hp = HpLim, revive_ref = undefined},
            NewRoleList = lists:keystore(RoleId, #dungeon_role.id, RoleList, NewDungeonRole),
            NewState = State#dungeon_state{role_list = NewRoleList}
    end,
    {noreply, NewState};

%% 假人复活定时 {rivive, Hp, X, Y}
do_handle_info({dummy_revive, FromAid, _DieDummyId, ObjId, Args}, State) ->
    #dungeon_state{typical_data = TypicalData} = State,
    DunDummys = maps:get(?DUN_STATE_SPECIAL_KEY_DUMMY, TypicalData, []),
    case lists:keyfind(ObjId, #dungeon_dummy.id, DunDummys) of
        #dungeon_dummy{typical_data = DummyTypicalData} ->
            Ref = maps:get(?DUN_DUMMY_GUARD_REVIVE_REF, DummyTypicalData, undefined),
            util:cancel_timer(Ref),
            % mon_mgr:send();
            [_X, _Y, HpLim|_] = Args,
            % ?ERR("~p ~p ~p ~p", [FromAid, DieDummyId, ObjId, HpLim]),
            mon_mgr:send(FromAid, ObjId, {'change_attr', [{state, back}, {hp, HpLim}]}),
            {noreply, State};
        _ ->
            {noreply, State}
    end;

do_handle_info({apply, Mod, Fun, Args}, State) ->
    case catch Mod:Fun(State, Args) of
        NewState = #dungeon_state{} ->
            {noreply, NewState};
        {noreply, NewState} ->
            {noreply, NewState};
        {'EXIT', Error} ->
            ?ERR("mod_dungeon_info: apply error: ~p~n", [[Mod, Fun, Args, Error]]),
            {noreply, State};
        _ ->
            {noreply, State}
    end;

do_handle_info({dispatch_dun_event, Msg}, State) ->
    case catch lib_dungeon_distribute:dispatch_dun_event(Msg, State) of
        NewState when is_record(NewState, dungeon_state) ->
            {noreply, NewState};
        {noreply, NewState} when is_record(NewState, dungeon_state) ->
            {noreply, NewState};
        {'EXIT', Error} ->
            ?ERR("mod_dungeon_info dispatch_dun_event ~p ~n error: ~p ~n", [Msg, Error]),
            {noreply, State};
        _ ->
            {noreply, State}
    end; 

do_handle_info(stop, State) ->
    {stop, normal, State};

%% 默认匹配
do_handle_info(Info, State) ->
    catch ?ERR("mod_dungeon_info:handle_info not match: ~p", [Info]),
    {noreply, State}.
