%%%--------------------------------------
%%% @Module  : lib_joy_wish_act.hrl
%%% @Author  : lhy
%%% @Created : 2019-05-24
%%% @Description:  欢乐许愿
%%%--------------------------------------

-module(lib_joy_wish_act).
-include("custom_act.hrl").
-include("common.hrl").
-include("server.hrl").
-include("figure.hrl").
-include("errcode.hrl").
-include("def_fun.hrl").
-include("goods.hrl").
-include("def_module.hrl").
-include("joy_wish.hrl").
-include("role.hrl").
-include("custom_act_draw_record.hrl").
-include("predefine.hrl").
-include("def_goods.hrl").
-export([
        login/1                    %% 登录
       ,act_end/2                  %% 活动结束,清除抽奖次数
       ,reset/3                    %% 重置玩家抽奖次数
       ,wish/6                     %% 许愿
       ,get_record_config_local/3  %% 活动本服抽奖记录的记录限制条件
]).

login(RoleId) ->
    List = db_joy_wish_select(RoleId),
    F = fun([Type, SubType, Times], JoyWish) ->
        maps:put({Type, SubType}, Times, JoyWish)
    end,
    JoyWishMaps = lists:foldl(F, #{}, List),
    #joy_wish{wish_times = JoyWishMaps}.

act_end(Type, SubType) ->
    spawn(fun()-> db_joy_wish_delete(Type, SubType) end),
    OnlineList = ets:tab2list(?ETS_ONLINE),
    IdList = [[PlayerId, Type, SubType] || #ets_online{id = PlayerId}<-OnlineList],
    lists:foreach(fun do_act_end/1, IdList).

do_act_end([PlayerId, Type, SubType]) ->
    lib_player:apply_cast(PlayerId, 2, lib_joy_wish_act, reset, [Type, SubType]).

reset(PS, Type, SubType) ->
    #player_status{joy_wish = #joy_wish{wish_times = JoyWishMaps} = JoyWishStatus} = PS,
    NewJoyWishMaps = maps:remove({Type, SubType}, JoyWishMaps),
    PS#player_status{joy_wish = JoyWishStatus#joy_wish{wish_times = NewJoyWishMaps}}.

wish(PS, Type, SubType, WishType, Wlv, BuyType) ->
    CheckList = [{check_draw_type, WishType}
                ,{check_act_cfg, Type, SubType}],
    case check_args(CheckList) of
        true ->
            #custom_act_cfg{condition = Condition} = lib_custom_act_util:get_act_cfg_info(Type, SubType),
            case WishType of
                1 ->
                    Times = 1,
                    {once_wish, Cost} = lists:keyfind(once_wish, 1, Condition);
                2 ->
                    Times = 10,
                    {ten_wish, Cost} = lists:keyfind(ten_wish, 1, Condition)
            end,
            case BuyType of
                1 ->
                    case lib_goods_api:cost_objects_with_auto_buy(PS, Cost, joy_wish, "") of
                        {true, NewPS, _Cost} ->
                            do_wish(NewPS, Wlv, WishType, Times, Type, SubType, Cost);
                        {false, ErrCode, _NewPS} ->
                            {false, ErrCode}
                    end;
                _ ->
                    case lib_goods_api:cost_object_list_with_check(PS, Cost, joy_wish, "") of
                        {true, NewPS,_} ->
                            do_wish(NewPS, Wlv, WishType, Times, Type, SubType, Cost);
                        {false, ErrCode, _NewPS} ->
                            {false, ErrCode}
                    end
            end;
        {false, ErrCode} ->
            {false, ErrCode}
    end.

do_wish(Player, Wlv, WishType, Times, Type, SubType, Cost) ->
    #player_status{joy_wish = #joy_wish{wish_times = JoyWishMaps} = JoyWish, id = RoleId} = Player,
    GradeIds = lib_custom_act_util:get_act_reward_grade_list(?CUSTOM_ACT_TYPE_JOY_WISH, SubType),
    RewardWeightList = get_wish_reward(GradeIds, SubType, Wlv),
    {RewardList, _BroadcastList, GradeIdList} = do_wish_core(Type, SubType, Times, RewardWeightList, [], [], []),
    %% 更新许愿记录
    {ok, PS} = lib_draw_record_api:refresh_local_draw_record(Player, Type, SubType, GradeIdList),
    %% 日志
    lib_log_api:log_joy_wish(PS#player_status.id, ?CUSTOM_ACT_TYPE_JOY_WISH, SubType, Wlv, WishType, RewardList, Cost),
    OldTimes = maps:get({Type, SubType}, JoyWishMaps, 0),
    db_joy_wish_replace(RoleId, Type, SubType, OldTimes + Times),
    NewJoyWishMaps = maps:put({Type, SubType}, OldTimes + Times, JoyWishMaps),
    TmpPS = PS#player_status{joy_wish = JoyWish#joy_wish{wish_times = NewJoyWishMaps}},
    ActName = lib_custom_act_api:get_act_name(Type, SubType),
    Produce = #produce{type = joy_wish, reward = RewardList, show_tips = 1,
                               title   = utext:get(3310009, [ActName]),
                               content = utext:get(3310010, [ActName])},
    {ok, NewPS} = lib_goods_api:send_reward_with_mail(TmpPS, Produce, ?MOD_AC_CUSTOM),
    % F2 = fun({GoodsTypeId, Num}) ->
    %        #ets_goods_type{goods_name = GoodsName, color = Color} = data_goods_type:get(GoodsTypeId),
    %        lib_chat:send_TV({all}, ?MOD_AC_CUSTOM, 26, [NewPS#player_status.figure#figure.name, Color, GoodsName, Num])
    %end,
    %lists:foreach(F2, BroadcastList),
    {true, RewardList, NewPS}.

do_wish_core(_Type, _SubType, 0, _WeightList, RewardList, BroadcastList, GradeIdList) -> {RewardList, BroadcastList, GradeIdList};
do_wish_core(Type, SubType, Times, WeightList, RewardList, BroadcastList, GradeIdList) ->
    case urand:rand_with_weight(WeightList) of
        false ->
            ?ERR("joy wish weight rand null~n", []),
            do_wish_core(Type, SubType, Times - 1, WeightList, RewardList, BroadcastList, GradeIdList);
        [GradeId, Condition] ->
            case lib_custom_act_util:get_act_reward_cfg_info(Type, SubType, GradeId) of
                #custom_act_reward_cfg{reward = Reward} ->
                    skip;
                _ ->
                    Reward = []
            end,
            NewBroadcastList = case lists:keyfind(is_tv, 1, Condition) of
                {is_tv, 1} ->
                    Tmp = [{GoodsTypeId, Num} || {_, GoodsTypeId, Num} <- Reward],
                    Tmp ++ BroadcastList;
                _ ->
                    BroadcastList
            end,
            do_wish_core(Type, SubType, Times - 1, WeightList, Reward ++ RewardList, NewBroadcastList, [GradeId | GradeIdList])
    end.

get_wish_reward(GradeIds, SubType, Wlv) ->
    F = fun(GradeId, RewardWeightList) ->
        case lib_custom_act_util:get_act_reward_cfg_info(?CUSTOM_ACT_TYPE_JOY_WISH, SubType, GradeId) of
            #custom_act_reward_cfg{condition = Condition} ->
                do_get_wish_reward(RewardWeightList, Condition, GradeId, Wlv);
            _ ->
                RewardWeightList
        end
    end,
    lists:foldl(F, [], GradeIds).

do_get_wish_reward(RewardWeightList, Condition, GradeId, Wlv) ->
    case lists:keyfind(reward_type, 1, Condition) of
        {reward_type, 0} ->
            case lists:keyfind(wlv, 1, Condition) of
                {wlv, [LowerWlv, UpperWlv]} when Wlv >= LowerWlv andalso Wlv =< UpperWlv ->
                    Args = [GradeId, Condition],
                    case lists:keyfind(weight, 1, Condition) of
                        {weight, Weight} ->
                            [{Weight, Args} | RewardWeightList];
                        _ ->
                            RewardWeightList
                    end;
                _ ->
                    RewardWeightList
            end;
        _ ->
            RewardWeightList
    end.

%% 活动本服抽奖记录的记录限制条件
get_record_config_local(Type, SubType, GradeId) ->
    case lib_custom_act_util:get_act_reward_cfg_info(Type, SubType, GradeId) of
        #custom_act_reward_cfg{reward = [{_, GoodsTypeId, _} | _]} ->
            case data_goods_type:get(GoodsTypeId) of
                #ets_goods_type{color = Color} when Color >= ?PURPLE ->
                    true;
                _ ->
                    false
            end;
        _ ->
            false
    end.

%% ------------------------------------- check function --------------------------------
%% 检查参数
check_args([]) -> true;
check_args([H | T]) ->
    case do_check(H) of
        true ->
            check_args(T);
        {false, ErrCode} ->
            {false, ErrCode}
    end.

%% 检查寻宝类型
do_check({check_draw_type, WishType}) ->
    case WishType of
        1 ->
            true;
        2 ->
            true;
        _ ->
            {false, ?ERRCODE(err430_args_type_error)}
    end;
do_check({check_act_cfg, Type, SubType}) ->
    case lib_custom_act_util:get_act_cfg_info(Type, SubType) of
        #custom_act_cfg{condition = Condition} ->
            OnceCost = case lists:keyfind(once_wish, 1, Condition) of
                {once_wish, _Cost1} when is_list(_Cost1) ->
                    true;
                _ ->
                    false
            end,
            TenCost = case lists:keyfind(ten_wish, 1, Condition) of
                {ten_wish, _Cost2} when is_list(_Cost2) ->
                    true;
                _ ->
                    false
            end,
            if
                OnceCost == true andalso TenCost == true ->
                    true;
                true ->
                    {false, ?ERRCODE(missing_config)}
            end;
        _ ->
            {false, ?ERRCODE(missing_config)}
    end.

%% --------------------------------- db ------------------------------------------------
db_joy_wish_select(RoleId) ->
    SQL = io_lib:format(?sql_joy_wish_select, [RoleId]),
    db:get_all(SQL).
db_joy_wish_replace(RoleId, Type, SubType, Times) ->
    SQL = io_lib:format(?sql_joy_wish_replace,[RoleId, Type, SubType, Times]),
    db:execute(SQL).
db_joy_wish_delete(Type, SubType) ->
    SQL = io_lib:format(?sql_joy_wish_delete, [Type, SubType]),
    db:execute(SQL).
