%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     个人差异化定制活动-限购礼包
%%% @end
%%%-------------------------------------------------------------------
-module(custom_act_limit_gift).
-author("liushl").

-include("custom_act.hrl").
-include("errcode.hrl").
-include("server.hrl").
-include("def_goods.hrl").
-include("common.hrl").
-include("goods.hrl").
-include("figure.hrl").
%% API
-export([
    count_reward_progress/4,
    check_receive_reward_conditions/3,
    receive_reward/4,
    check_reward_receive_times/3,
    count_receive_times/3
]).

%% @doc 活动派发接口:计算奖励相关的达成进度
count_reward_progress(Player, ActInfo, CommonProgress, RewardCfg) ->
    #act_info{stime = Stime, etime = ETime} = ActInfo,
    #custom_act_reward_cfg{condition = Conditions} = RewardCfg,
    case lists:keyfind(recharge_gold, 1, Conditions) of
        {recharge_gold, _} ->
            lib_recharge_data:get_my_recharge_between(Player#player_status.id, Stime, ETime);
        _ ->
            CommonProgress
    end.

%% @doc 活动派发接口:奖励领取条件
check_receive_reward_conditions(Player, ActInfo, RwCfg) ->
    #act_info{stime = Stime, etime = ETime} = ActInfo,
    #custom_act_reward_cfg{condition = Conditions} = RwCfg,
    case lists:keyfind(recharge_gold, 1, Conditions) of
        {recharge_gold, Value} ->
            X = lib_recharge_data:get_my_recharge_between(Player#player_status.id, Stime, ETime),
            case X >= Value of
                true  ->
                    true;
                false ->
                    {false, ?ERRCODE(err331_act_can_not_get)}
            end;
        _ ->
            true
    end.

%% @doc 活动派发接口:判断购买次数
check_reward_receive_times(Player, ActInfo, #custom_act_reward_cfg{condition = Condition} = RewardCfg) ->
    BuyCount = count_receive_times(Player, ActInfo, RewardCfg),
    case lists:keyfind(limit_times, 1, Condition) of
        {_, LimitTimes}  ->
            LimitTimes;
        _ ->
            %% 没有配置。默认限购1次
            LimitTimes = 1
    end,
    case BuyCount < LimitTimes of
        true  ->
            {true, BuyCount + 1};
        false ->
            false
    end.

%% @doc 活动派发接口:统计已购买次数
count_receive_times(Player, #act_info{key = {ActType, SubType}, stime = Stime, etime = Etime}, #custom_act_reward_cfg{grade = GradeId}) ->
    StatusCustomAct = Player#player_status.status_custom_act,
    RewardMap = StatusCustomAct#status_custom_act.reward_map,
    case maps:get({ActType, SubType, GradeId}, RewardMap, []) of
        #reward_status{utime = Utime, receive_times = ReceiveTimes}
            when Utime >= Stime, Utime =< Etime, ReceiveTimes > 0 ->
            ReceiveTimes;
        _ ->
            0
    end.

%% @doc 活动派发接口：购买礼包
receive_reward(Player, Type, SubType, GradeId) ->
    case receive_reward_do(Player, Type, SubType, GradeId) of
        {true, Player1, Reward} ->
            Produce = #produce{
                type = custom_act, subtype = Type, reward = Reward
                ,remark = ulists:concat(["type:", Type, " subtype:", SubType, " grade:", GradeId])
            },
            Player2 = lib_goods_api:send_reward(Player1, Produce),
            #player_status{figure = #figure{lv = Lv, vip = Vip}} = Player2,
            lib_log_api:log_custom_act_reward(Player#player_status.id, Type, SubType, GradeId, 0, Reward, [],
                Vip, Lv, Player#player_status.gold, Player2#player_status.gold, Player#player_status.bgold, Player2#player_status.bgold, utime:unixtime()),
            {ok, BinData} = pt_331:write(33105, [?SUCCESS, Type, SubType, GradeId]),
            lib_server_send:send_to_sid(Player#player_status.sid, BinData),
            {ok, Player2};
        {false, Error} ->
            {ok, BinData} = pt_331:write(33105, [Error, Type, SubType, GradeId]),
            lib_server_send:send_to_sid(Player#player_status.sid, BinData),
            ok
    end.

%% 购买
receive_reward_do(Player, Type, SubType, GradeId) ->
    case custom_act_personal:is_personal_act_open(Player, Type, SubType) of
        {true, ActInfo} ->
            case lib_custom_act_check:check_receive_reward_normal(Player, ActInfo, GradeId) of
                {true, ActInfo, NewReceiveTimes, RewardList, RewardCfg} ->
                    case calc_buy_price(Player, RewardCfg, ActInfo) of
                        true ->
                            %% 先更新购买状态
                            Player1 = lib_custom_act:update_receive_times(Player, Type, SubType, GradeId, NewReceiveTimes),
                            {true, Player1, RewardList};
                        {true, Cost} ->
                            Remark = ulists:concat(["type:", Type, " subtype:", SubType, " grade:", GradeId]),
                            case lib_goods_api:cost_object_list_with_check(Player, Cost, custom_act, Remark) of
                                {true, Player1, _} ->
                                    %% 先更新购买状态
                                    Player2 = lib_custom_act:update_receive_times(Player1, Type, SubType, GradeId, NewReceiveTimes),
                                    {true, Player2, RewardList};
                                {false, Error, _} ->
                                    {false, Error}
                            end;
                        _ ->
                            {false, ?MISSING_CONFIG}
                    end;
                {false, Error} ->
                    {false, Error}
            end;
        false ->
            {false, ?ERRCODE(err331_act_closed)}
    end.

%% 计算购买价格
calc_buy_price(Player, RwCfg, ActInfo) ->
    #custom_act_reward_cfg{condition = Condition} = RwCfg,
    #act_info{stime = StartTime,  etime = EndTime} = ActInfo,
    case lists:keyfind(limit_cost, 1, Condition) of
        {_, 0} ->
            true;
        {_, Price} ->
            {true, [{?TYPE_GOLD, 0, Price}]};
        _ ->
            %% 达到充值额度可以直接领取
            case lists:keyfind(recharge_gold, 1, Condition) of
                {_, Gold} ->
                    Recharge = lib_recharge_data:get_my_recharge_between(Player#player_status.id, StartTime, EndTime),
                    Recharge >= Gold;
                _ ->
                    false
            end
    end.