%% -----------------------------------
%% desc  :材料副本
%% module:lib_dungeon_material.erl
%% author:hh
%% time  :19/11/08
%% -----------------------------------


-module(lib_dungeon_material).

-export([
    push_settlement/2
    ,get_role_rec/6
    ,calc_score_rewards/3
    ,handle_score_reward_rec/3
    ,handle_dungeon_result/1
    ,get_role_dun_born_xy/4
    ,role_score_rewarded_update/2
    ,update_role_pass_time/2
    ,dispatch_dun_event/2
    
    ,start_dun_flop/3
    ]).

-include("dungeon.hrl").
-include("common.hrl").
-include("predefine.hrl").
-include("figure.hrl").
-include("server.hrl").
-include("def_goods.hrl").

%% 特定事件自己拦截处理,否则默认走回dungeon_default:dispatch_dun_event/2处理
%% 通用默认操作
dispatch_dun_event(_Msg, State) ->
    dungeon_default:dispatch_dun_event(_Msg, State).

%% 获取副本三星评分奖励领取与否
get_role_rec(_DunId, _DunType, _RoleId, DungeonRec, _, TypicalData) ->
    IsScoreRewarded = case lists:keyfind(?DUNGEON_REC_DATA, 1, DungeonRec) of
        {_, 1} -> true;
        _      -> false
    end,
    maps:put(?DUNGEON_REC_DATA, IsScoreRewarded, TypicalData).

%% 结算展示
push_settlement(State, DungeonRole) ->
    #dungeon_state{
        result_type    = ResultType,
        result_subtype = ResultSubType,
        dun_id         = DunId,
        scene_id       = SceneId,
        wave_num       = WaveNum
    } = State,
    #dungeon_role{node = Node, id = RoleId, sid = Sid, calc_reward_list = RewardList, drop_reward_list = DropRewardList, custom_reward_list = CustomReward} = DungeonRole,
    %% 翻牌逻辑
    ResultType == ?DUN_RESULT_TYPE_SUCCESS andalso material_flop(DunId, DungeonRole),
    CustomSizeData = lib_dungeon_distribute:pack_account_kv_data(State, RoleId),
    FinalRewardList = lists:append([RewardList, DropRewardList]),
    {ok, BinData} = pt_610:write(61003, [ResultType, ResultSubType, DunId, SceneId, WaveNum, FinalRewardList, CustomReward,CustomSizeData]),
    lib_server_send:send_to_sid(Node, Sid, BinData).


%% 计算评分奖励
calc_score_rewards(_DunType, DunId, DungeonRole) ->
    #dungeon_role{figure = #figure{lv = Lv}, typical_data = TypicalData, grade_progress = GradeProgress} = DungeonRole,
    IsScoreRewarded = maps:get(?DUNGEON_REC_DATA, TypicalData, false),
    case GradeProgress of
        #dungeon_role_grade{map = Maps} ->
            case data_dungeon_grade:get_dungeon_grade(DunId, Lv) of
                #dungeon_grade{condition = Condition, reward = Rewards} ->
                            StarNum = dungeon_default:calc_dun_score(Maps),
                            ConfigMaxStar = length(Condition),
                            if StarNum >= ConfigMaxStar andalso (not IsScoreRewarded) ->
                                    {[true], Rewards};
                                true ->
                                    {[false], []}
                            end;
                _ ->
                    {[false], []}
            end;
        _ ->
            {[false], []}
    end.

get_role_dun_born_xy(State, _, X, Y) ->
    #dungeon_state{dun_id = DunId, wave_num = Wave} = State,
    case data_dungeon_wave:get_dun_wave(DunId, Wave) of
        #base_dun_wave_cfg{born_xy = [{CfgX, CfgY}|_]} ->
            {CfgX, CfgY};
        _ ->
            {X, Y}
    end.

%% 
handle_score_reward_rec(DungeonRole, DunId, ExtraArgs) ->
    #dungeon_role{id = RoleId, node = Node} = DungeonRole,
    [IsScoreRewarded|_] = ExtraArgs,
    if IsScoreRewarded ->
            lib_player:apply_cast(Node, RoleId, ?APPLY_CAST_SAVE, ?NOT_HAND_OFFLINE, ?MODULE, role_score_rewarded_update, [DunId]);
        true ->
            ok
    end.

%% 材料副本,三星评分奖励只能领取一次,不能重复领取
role_score_rewarded_update(Player, DunId) ->
    #player_status{id = RoleId, dungeon_record = DungeonRec} = Player,
    DunRec = maps:get(DunId, DungeonRec, []),
    {IsUpdate, NewDunRec} = case lists:keyfind(?DUNGEON_REC_DATA, 1, DunRec) of
        {_, 1} ->
            {false, DunRec};
        _ ->
            {true, lists:keystore(?DUNGEON_REC_DATA, 1, DunRec, {?DUNGEON_REC_DATA, 1})}
    end,
    if IsUpdate ->
            lib_dungeon:save_dungeon_record(RoleId, DunId, NewDunRec),
            NewDungeonRec = maps:put(DunId, NewDunRec, DungeonRec),
            NewPlayer = Player#player_status{dungeon_record = NewDungeonRec},
            {ok, NewPlayer};
        true ->
            {ok, Player}
    end.

material_flop(DunId, DungeonRole) ->
    #dungeon_role{node = Node, id = RoleId} = DungeonRole,
    case data_dungeon:get_dun(DunId) of
        #dun_cfg{type = DunType, flop_pools = [_|_]} -> %% 有翻牌配置即要求翻牌
            lib_player:apply_cast(Node, RoleId, ?APPLY_CAST_SAVE, ?NOT_HAND_OFFLINE, lib_dungeon_flop, start_dun_flop, [DunType, DunId]);
        _ -> ok
    end.

start_dun_flop(Player, DunType, DunId) ->
    case data_dungeon:get_dun(DunId) of
        #dun_cfg{type = DunType, flop_pools = [_|_]} ->
            {_, NewPlayer} = lib_dungeon_flop:start_dun_flop(Player, DunType, DunId),
            NewPlayer;
        _ ->
            Player
    end.

handle_dungeon_result(State) ->
    #dungeon_state{dun_id = DunId, result_type = ResultType, role_list = RoleList} = State,
    if ResultType == ?DUN_RESULT_TYPE_SUCCESS ->
            [lib_player:apply_cast(Node, RoleId, ?APPLY_CAST_SAVE, ?NOT_HAND_OFFLINE, ?MODULE, update_role_pass_time, [DunId]) || #dungeon_role{node = Node, id = RoleId} <- RoleList];
        true ->
            skip
    end,
    State.

update_role_pass_time(Player, DunId) ->
    #player_status{id = RoleId, dungeon_record = DungeonRecs} = Player,
    DunRec = maps:get(DunId, DungeonRecs, []),
    case lists:keyfind(?DUNGEON_REC_PASSTIME, 1, DunRec) of
        {_, _} ->
            {ok, Player};
        _ ->
            NewDunRec = lists:keystore(?DUNGEON_REC_PASSTIME, 1, DunRec, {?DUNGEON_REC_PASSTIME, utime:unixtime()}),
            lib_dungeon:save_dungeon_record(RoleId, DunId, NewDunRec),
            NewDungeonRecs = maps:put(DunId, NewDunRec, DungeonRecs),
            {ok, Player#player_status{dungeon_record = NewDungeonRecs}}
    end.