%% ---------------------------------------------------------------------------
%% @doc 定制活动-商城抢购。
%% @author zmh
%% @since  2020-07-06
%% ---------------------------------------------------------------------------
-module(limit_mall).


-export([
    ask_reward_status/3
    ,check/1
    ,check_cost/5
    ,receive_reward/4
]).


-include("custom_act.hrl").
-include("common.hrl").
-include("server.hrl").
-include("figure.hrl").
-include("errcode.hrl").
-include("goods.hrl").
-include("def_module.hrl").
-include("def_goods.hrl").
-include("rec_event.hrl").
-include("def_event.hrl").

ask_reward_status(Player,Type,SubType)->
    #player_status{sid=Sid,figure=#figure{lv=Lv},status_custom_act = StatusCustomAct}=Player,
    RewardMap  = StatusCustomAct#status_custom_act.reward_map,
    RewardList = maps:to_list(RewardMap),
    Wares = filter_wares(Type,SubType,RewardList,[]),
    All   = lib_custom_act_util:get_act_reward_grade_list(Type, SubType),
    NWares   = to_client_ware(All,Type,SubType,Lv,Wares,[]),
    {ok,Bin} = pt_331:write(33104,[Type,SubType,NWares]),
    lib_server_send:send_to_sid(Sid,Bin),
    {ok,Player}.

to_client_ware([], _Type, _SubType,_Lv,_,NWares)->
    NWares;
to_client_ware([H|T],Type, SubType,Lv,Wares,NWares)->
    case lib_custom_act_util:get_act_reward_cfg_info(Type,SubType,H) of
        #custom_act_reward_cfg{
            name = Name,
            desc = Desc,
            condition = Condition,
            format = Format,
            reward = Rewards
        }->
            case lists:keyfind(H,1,Wares) of
                {_,CurV}->
                    skip;
                _->
                    CurV = 0
            end,
            case lists:keyfind(limit_times,1,Condition) of
                {_,Max}->
                    skip;
                _->
                    Max = 0
            end,
            CurS = case CurV>=Max of
                true->
                    2;
                _->
                    0
            end,
            ConditionStr = util:term_to_string(Condition),
            RewardStr = util:term_to_string(Rewards),
            Data = {H,Format,CurV,CurS,0,Name,Desc,ConditionStr,RewardStr},
            to_client_ware(T,Type,SubType,Lv,Wares,[Data|NWares]);
        _->
            to_client_ware(T,Type,SubType,Lv,Wares,NWares)
    end.


filter_wares(_Type,_SubType,[],Wares)->
    Wares;
filter_wares(Type,SubType,[{{T,S,G},#reward_status{receive_times = Times}}|Tail],Wares)->
    case T =:= Type andalso SubType =:= S of
        true->
            filter_wares(Type,SubType,Tail,[{G,Times}|Wares]);
        _->
            filter_wares(Type,SubType,Tail,Wares)
    end.


%%购买
receive_reward(Player,Type,SubType,Grade)->
    #player_status{sid=Sid,status_custom_act = StatusCustomAct}=Player,
    Num = 1,

    RewardMap = StatusCustomAct#status_custom_act.reward_map,
    RewardList = maps:to_list(RewardMap),
    Wares = filter_wares(Type,SubType,RewardList,[]),

    Config = lib_custom_act_util:get_act_reward_cfg_info(Type,SubType,Grade),
    {Res,NewPlayer} = case check_cost(Player,Wares,Grade,Num,Config) of
        {true,Gain,NewReceiveTimes,NPlayer0}->
            NPlayer1 = lib_custom_act:update_receive_times(NPlayer0, Type, SubType, Grade, NewReceiveTimes),
            About = io_lib:format("~w,~w,~w", [Type,SubType,Grade]),
            Produce = #produce{type = limit_mail_buy, subtype = Type, reward = Gain,remark = About},
            {ok,NPlayer} = lib_goods_api:send_reward_with_mail(NPlayer1, Produce,?MOD_AC_CUSTOM),
            lib_log_api:custom_act_reward_log(NPlayer, Player, Type, SubType, Grade,Gain),
            {?SUCCESS,NPlayer};
        {false,Err}->
            {Err,Player}
    end,
    {ok, BinData} = pt_331:write(33105, [Res,Type, SubType,Grade]),
    lib_server_send:send_to_sid(Sid, BinData),
    {ok, NewPlayer}.


%% @doc 扣除消耗
check_cost(Player,Wares,Grade,Num,#custom_act_reward_cfg{type=Type,subtype=SubType,condition=Condition,reward=Rewards}) ->
    #player_status{figure=#figure{lv=Lv,vip=Vip}}=Player,
    case lists:keyfind(Grade,1,Wares) of
        {_,CurV}->
            skip;
        _->
            CurV = 0
    end,
    case lists:keyfind(limit_times,1,Condition) of
        {_,Max}->
            skip;
        _->
            Max = missing_config
    end,
    case lists:keyfind(show_level_range,1,Condition) of
        {_,LvMin,LvMax}->
            skip;
        _->
           LvMin=999999,LvMax=999999
    end,
    case lists:keyfind(gold_type,1,Condition) of
        {_,GType}->
            skip;
        _->
            GType = missing_config
    end,
    case lists:keyfind(limit_cost,1,Condition) of
        {_,Price}->
            skip;
        _->
           Price = missing_config
    end,
    case lists:keyfind(limit_vip,1,Condition) of
        {_,NeedVip}->
            skip;
        _->
            NeedVip = 0
    end,
    Cost = [{GType,0,Price*Num}],
    Gain = [{T,K,V*Num}||{T,K,V}<-Rewards],
    HasNum = CurV+Num,
    CheckList = [
        {check_cfg_price,GType,Price},
        {check_cfg_lv,{LvMin,LvMax},Lv},
        {check_cfg_vip,NeedVip,Vip},
        {check_cfg_limit,Max,HasNum},
        {check_act_open,Type,SubType},
        {check_cost,Player,Cost,Price}
    ],
    case util:check_lists(?MODULE,CheckList) of
        {ok,NPlayer}->
            {true,Gain,HasNum,NPlayer};
        {false,Err}->
            {false,Err}
    end;
check_cost(_Player,_Wares,_Grade,_Num,_)-> {false,?ERRCODE(missing_config)}.


check({check_act_open,Type,SubType})->
    case lib_custom_act_api:is_open_act(Type, SubType) of
        true->
            true;
        _->
            {false,?ERRCODE(err157_act_not_open)}
    end;
check({check_cfg_price,Type,Price})->
    case is_integer(Type) of
        true when is_integer(Price) ->
            true;
        _->
            {false,?ERRCODE(missing_config)}
    end;
check({check_cfg_lv,LvMax,Lv})->
    case LvMax of
        {Min,Max} when Lv>=Min andalso Lv=< Max->
            true;
        _->
            {false,?ERRCODE(err331_lv_unreach)}
    end;
check({check_cfg_vip,NeedVip,Vip})->
    case Vip>=NeedVip of
        true->
            true;
        _->
            {false,?ERRCODE(vip_limit)}
    end;
check({check_cfg_limit,Max,Num})->
    case is_integer(Max) of
        true when Num=<Max->
            true;
        _->
            {false,?ERRCODE(err331_over_limit_num)}
    end;
check({check_cost,Role,_Cost,Price}) when Price=<0 ->
    {ok,Role};
check({check_cost,Role,Cost,_Price})->
    case lib_goods_api:cost_object_list_with_check(Role, Cost, limit_mall_buy, "limit_mall_buy") of
        {true, TmpRole,_} ->
            {ok, TmpRole};
        {false, Err,_} ->
            {false,Err}
    end.





