%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%1、玩法是一个抽奖活动，通过使用金击子可以敲打人参果树，果树会随机掉落一个奖励
%%2、奖励被包装为3个品质，分别为金人参果、蓝果、白果，即开奖的时候是先进行品质展示，再进行奖励展示
%%3、玩家进行敲打的时候，根据抽奖结果，果树会进行对应的掉落表现，播放一段人参果被击落的特效，然后展示人参果，最后展示人参果中包含的奖励
%%4、游戏每一定敲打次数会触发必中金人参果的设定，该次敲打必中金人参果
%%% @end
%%%-------------------------------------------------------------------
-module(custom_act_tree_lottery).
-author("liushl").

-include("custom_act.hrl").
-include("server.hrl").
-include("figure.hrl").
-include("def_module.hrl").
-include("errcode.hrl").
%% API
-export([
    get_base_info/1,
    lottery/3,
    get_score_reward/2
]).
-compile(export_all).

%% @doc 抽奖基本信息
get_base_info(SubType) ->
    Type = ?CUSTOM_ACT_TYPE_TREE_LOTTERY,
    case lib_custom_act_api:is_open_act(Type, SubType) of
        true  ->
            #custom_act_data{
                act_data = ActData
            } = custom_act_data(Type, SubType),
            #custom_act_tree_lottery{
                next_hit = NextHit
                , score = Score
                , free_count = FreeUse
            } = ActData,
            FreeCount = get_free_count(Type, SubType),
            [SubType, NextHit, Score, max(0, FreeCount - FreeUse)];
        false ->
            false
    end.

get_free_count(Type, SubType) ->
    case lib_custom_act_util:keyfind_act_condition(Type, SubType, free_draw_times) of
        {free_draw_times, _FreeCount} when is_integer(_FreeCount) ->
            _FreeCount;
        _ ->
            0
    end.

%% @doc 抽奖-单抽/10连
lottery(Player, SubType, Kind) ->
    Type = ?CUSTOM_ACT_TYPE_TREE_LOTTERY,
    Cost = case Kind of
               1  -> lib_custom_act_util:get_custom_act_kv(Type, cost_one, false);
               2  -> lib_custom_act_util:get_custom_act_kv(Type, cost_ten, false)
           end,
    case lib_custom_act_api:is_open_act(Type, SubType) andalso Cost =/= false of
        true  ->
            #player_status{
                id = RoleId,
                figure = #figure{name = Name} = Figure
            } = Player,
            #custom_act_data{
                act_data = ActData
            } = CustomData = custom_act_data(Type, SubType),
            Times = case Kind of
                        1  -> 1;
                        2  -> 10
                    end,
            FreeCount = get_free_count(Type, SubType),
            case FreeCount > 0 andalso Kind =:= 1 of
                true  ->
                    FreeUse = ActData#custom_act_tree_lottery.free_count,
                    case FreeUse < FreeCount of
                        true  ->
                            FreeActData = ActData#custom_act_tree_lottery{free_count = FreeUse + 1},
                            FinalCost = [];
                        false ->
                            FreeActData = ActData,
                            FinalCost = Cost
                    end;
                false ->
                    FreeActData = ActData,
                    FinalCost = Cost
            end,
            case calc_reward_grades(Type, SubType, Times, FreeActData, []) of
                {PickGrades, NewActData} when PickGrades =/= [] ->
                    case lib_goods_api:cost_objects_with_auto_buy(Player, FinalCost, custom_act, "") of
                        {true, Player1, _} ->
                            lib_custom_act_data:save_custom_data(RoleId,
                                CustomData#custom_act_data{act_data = NewActData, time = utime:unixtime()}
                            ),
                            {SendList, RewardList} =
                                lists:foldl(
                                    fun(Grade, {SendInfo, GoodsList}) ->
                                        #custom_act_reward_cfg{
                                            reward = [{_, GoodsId, GoodsNum}] = Add,
                                            condition = Condition
                                        } = lib_custom_act_util:get_act_reward_cfg_info(Type, SubType, Grade),
                                        case lists:keyfind(tv_show, 1, Condition) of
                                            {tv_show, 1} ->
                                                lib_chat:send_TV({all}, ?MOD_AC_CUSTOM, 39, [Name, GoodsId, GoodsNum]);
                                            _ ->
                                                ok
                                        end,
                                        case lists:keyfind(type, 1, Condition) of
                                            {type, AwardType} ->
                                                AwardType;
                                            _ ->
                                                AwardType = 3
                                        end,
                                        {[{AwardType, GoodsId, GoodsNum}|SendInfo], Add ++ GoodsList}
                                    end, {[], []}, PickGrades
                                ),
                            Player2 = lib_goods_api:send_reward(Player1, RewardList, custom_act),
                            lib_log_api:log_custom_act_reward(RoleId, Type, SubType, 0, 0, RewardList, util:term_to_bitstring(PickGrades), Figure#figure.vip, Figure#figure.lv,
                                Player#player_status.gold, Player2#player_status.gold, Player#player_status.bgold, Player2#player_status.bgold, utime:unixtime()),
                            {ok, Player2, SendList};
                        {false, Error, _} ->
                            {false, Error}
                    end;
                _ ->
                    {false, ?ERRCODE(err331_no_act_reward_cfg)}
            end;
        _ ->
            {false, ?ERRCODE(err331_act_closed)}
    end.

calc_reward_grades(_Type, _SubType, 0, ActData, Grades) ->
    {Grades, ActData};
calc_reward_grades(Type, SubType, Times, ActData, Grades) ->
    NewActData =
    case ActData#custom_act_tree_lottery.next_hit of
        1 ->
            %% 必出高品质
            Flag = 1,
            ActData#custom_act_tree_lottery{
                count = ActData#custom_act_tree_lottery.count + 1,
                next_hit = get_next_hit(Type),
                score = ActData#custom_act_tree_lottery.score + get_rand_score(Type)
            };
        NextHit ->
            %% 一般
            Flag = 0,
            ActData#custom_act_tree_lottery{
                count = ActData#custom_act_tree_lottery.count + 1,
                next_hit = NextHit - 1,
                score = ActData#custom_act_tree_lottery.score + get_rand_score(Type)
            }
    end,
    WeightList =
    lists:foldl(
        fun(Grade, Temp) ->
            #custom_act_reward_cfg{
                condition = Condition
            } = lib_custom_act_util:get_act_reward_cfg_info(Type, SubType, Grade),
            case lists:keyfind(type, 1, Condition) of
                {type, AwardType} ->
                    case (Flag == 1 andalso AwardType == 1)
                        orelse Flag == 0
                    of
                        true  ->
                            case lists:keyfind(weight, 1, Condition) of
                                {weight, Weight} ->
                                    [{Weight, Grade}|Temp];
                                _ ->
                                    Temp
                            end;
                        false ->
                            Temp
                    end;
                _ ->
                    Temp
            end
        end, [], lib_custom_act_util:get_act_reward_grade_list(Type, SubType)
    ),
    case urand:rand_with_weight(WeightList) of
        Id when is_integer(Id) ->
            calc_reward_grades(Type, SubType, Times - 1, NewActData, [Id|Grades]);
        _ ->
            {Grades, ActData}
    end.

%% @doc 领取积分奖励
get_score_reward(Player, SubType) ->
    Type = ?CUSTOM_ACT_TYPE_TREE_LOTTERY,
    case lib_custom_act_api:is_open_act(Type, SubType) of
        true ->
            #custom_act_data{
                act_data = ActData
            } = CustomData = custom_act_data(Type, SubType),
            #custom_act_tree_lottery{
                score = Score
            } = ActData,
            MaxScore = lib_custom_act_util:get_custom_act_kv(Type, blessing_value_max, max),
            Reward   = lib_custom_act_util:get_custom_act_kv(Type, blessing_reward, []),
            case Score >= MaxScore andalso Reward =/= [] of
                true  ->
                    NewActData = ActData#custom_act_tree_lottery{score = Score - MaxScore},
                    lib_custom_act_data:save_custom_data(Player#player_status.id,
                        CustomData#custom_act_data{act_data = NewActData, time = utime:unixtime()}
                    ),
                    Player2 = lib_goods_api:send_reward(Player, Reward, custom_act),
                    {ok, Player2};
                false ->
                    {false, ?ERRCODE(err331_act_can_not_get)}
            end;
        false ->
            {false, ?ERRCODE(err331_act_closed)}
    end.

custom_act_data(Type, SubType) ->
    #custom_act_data{
        act_data = ActData
    } = CustomData = lib_custom_act_data:custom_act_data(Type, SubType),
    NewActData =
    case ActData of
        #custom_act_tree_lottery{} -> ActData;
        _ ->
            #custom_act_tree_lottery{next_hit = get_next_hit(Type)}
    end,
    CustomData#custom_act_data{act_data = NewActData}.


get_next_hit(Type) ->
    lib_custom_act_util:get_custom_act_kv(Type, golden_pocket_times, 20).

get_rand_score(Type) ->
    [Min, Max] = lib_custom_act_util:get_custom_act_kv(Type, blessing_add_num, [0, 0]),
    urand:rand(Min, Max).