%% ---------------------------------------------------------------------------
%% @doc 福袋/红包。
%% @author zmh
%% @since  2020-10-19
%% ---------------------------------------------------------------------------
-module(lib_lucky_bag).


-export([
    vie_lucky_bag/2,
    check/1
]).


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


%% 福袋
vie_lucky_bag(0,Status)->
    #player_status{figure=#figure{name=RName}}=Status,
    Type  = ?CUSTOM_ACT_TYPE_LUCKY_BAG1,
    LTime = get_last_time(Type),
    Now = utime:unixtime(),
    ActCfg = lib_custom_act_util:get_act_cfg_info(Type,1),
    CheckList = [
        {check_act_cfg,ActCfg},
        {check_act_open,Type,1},
        {check_vie_cd,ActCfg,Now,LTime},
        {check_vie_do,ActCfg,Now}
    ],
    case util:check_lists(?MODULE,CheckList) of
        true->
            Grades = lib_custom_act_util:get_act_reward_grade_list(Type,1),
            WeightList = make_weights(Type,1,Grades,[]),
            Grade = urand:rand_with_weight(WeightList),
            case lib_custom_act_util:get_act_reward_cfg_info(Type,1,Grade) of
               #custom_act_reward_cfg{reward=Awards}->
                    skip;
                _->
                    Awards = []
            end,
            case Awards /= [] of
                true->
                    Produce = #produce{type = lucky_bag_vie, reward=Awards},
                    {ok, NStatus} = lib_goods_api:send_reward_with_mail(Status, Produce, ?MOD_AC_CUSTOM),
                    brocast_awards(RName,Type,Grade,Awards),
                    put({vie_lucky,Type},Now),
                    lib_log_api:custom_act_reward_log(NStatus, Status, Type, 1, 0, Awards);
                _->
                    NStatus = Status
            end,
            {ok,Now,Grade,NStatus};
        {false,Err}->
            {false,LTime,Err}
    end;
vie_lucky_bag(_OpTy,Status)->
    #player_status{id=RoleID,figure=#figure{name=RName}}=Status,
    Type  = ?CUSTOM_ACT_TYPE_LUCKY_BAG2,
    LTime = get_last_time(Type),
    Now = utime:unixtime(),
    ActCfg = lib_custom_act_util:get_act_cfg_info(Type,1),
    ActData =  lib_custom_act_data:custom_act_data(Type, 1),
    CheckList = [
        {check_act_cfg,ActCfg},
        {check_act_open,Type,1},
        {check_vie_cd,ActCfg,Now,LTime},
        {check_vie_do,ActData,ActCfg,Now}
    ],
    case util:check_lists(?MODULE,CheckList) of
        {ok,NActData}->
            Grades     = lib_custom_act_util:get_act_reward_cfg_list(Type,1),
            WeightList = make_weights(Type,1,Grades,[]),
            Grade = urand:rand_with_weight(WeightList),
            case lib_custom_act_util:get_act_reward_cfg_info(Type,1,Grade) of
               #custom_act_reward_cfg{reward=Awards}->
                    skip;
                _->
                    Awards = []
            end,
            case Awards /= [] of
                true->
                    Produce = #produce{type = lucky_bag_vie, reward=Awards},
                    {ok, NStatus} = lib_goods_api:send_reward_with_mail(Status, Produce, ?MOD_AC_CUSTOM),
                    brocast_awards(RName,Type,Grade,Awards),
                    put({vie_lucky,Type},Now),
                    lib_custom_act_data:save_custom_data(RoleID,NActData),
                    lib_log_api:custom_act_reward_log(NStatus, Status, Type, 1, 1, Awards);
                _->
                    NStatus = Status
            end,
            {ok,Now,Grade,NStatus};
        {false,Err}->
            {false,LTime,Err}
    end.

check({check_act_cfg,ActCfg})->
    case ActCfg of
        #custom_act_cfg{}->
            true;
        _->
            {false,?ERRCODE(missing_config)}
    end;
check({check_vie_cd,ActCfg,Now,LTime})->
    #custom_act_cfg{condition=Condition}=ActCfg,
    Pass = max(Now-LTime,0),
    case lists:keyfind(cold_down,1,Condition) of
        {_,Cd}->
            skip;
        _->
            Cd = 99999
    end,
    case Pass>=Cd of
        true->
            true;
        _->
            {false,{?ERRCODE(err331_vie_bag_cding),[max(Cd-Pass,0)]}}
    end;
check({check_vie_do,ActCfg,Now})->
    case calc_open(ActCfg,Now) of
        {true,_}->
            true;
        _->
            {false,?ERRCODE(err331_act_closed)}
    end;
check({check_vie_do, ActData,ActCfg,Now})->
    #custom_act_data{
        act_data = VieDatas
    } = ActData,
    #custom_act_cfg{condition=Condition}=ActCfg,
    case lists:keyfind(max_times,1,Condition) of
        {_,MTimes}->
            skip;
        _->
           MTimes = 0
    end,
    case calc_open(ActCfg,Now) of
        {true,Key}->
            case lists:keyfind(Key,1,VieDatas) of
                {_,V} when V<MTimes->
                    NVies = lists:keystore(Key,1,VieDatas,{Key,V+1}),
                    {ok,ActData#custom_act_data{act_data=NVies}};
                {_,_} ->
                    {false,{?ERRCODE(err331_vie_bag_max),[MTimes]}};
                _->
                    NVies = lists:keystore(Key,1,VieDatas,{Key,1}),
                    {ok,ActData#custom_act_data{act_data=NVies}}
            end;
        _->
            {false,?ERRCODE(err331_act_closed)}
    end;
check({check_act_open,Type,SubType})->
    case lib_custom_act_api:is_open_act(Type, SubType) of
        true->
            true;
        _->
            {false,?ERRCODE(err331_act_closed)}
    end.

calc_open(ActCfg,Now)->
    #custom_act_cfg{condition=Condition}=ActCfg,
    case lists:keyfind(open_time,1,Condition) of
        {_,OpTime}->
            skip;
        _->
            OpTime = []
    end,
    case lists:keyfind(last_time,1,Condition) of
        {_,CTime}->
            skip;
        _->
            CTime = 0
    end,
    UnixDate = utime:unixdate(Now),
    calc_open(OpTime,UnixDate,CTime,Now).

calc_open([],_,_,_)->
    false;
calc_open([{H,M}|T],UnixDate,CTime,Now)->
    STime = UnixDate+H*3600+60*M,
    ETime = STime+CTime,
    {{_,Mon,Day},_} = utime:get_logic_time(),
    case STime=<Now andalso Now=<ETime of
        true->
            {true,Mon*1000000+Day*10000+H*100+M};
        _->
            calc_open(T,UnixDate,CTime,Now)
    end.

get_last_time(Type)->
    Time = get({vie_lucky,Type}),
    case is_integer(Time) of
        true->
            Time;
        _->
            utime:unixtime()-120
    end.


%%拼接权重列表
make_weights(_Type,_SubType,[],WeightList)->
    WeightList;
make_weights(Type,SubType,[H|T],WeightList)->
    case lib_custom_act_util:get_act_reward_cfg_info(Type,SubType,H) of
        #custom_act_reward_cfg{condition=Condition}->
            case lists:keyfind(weight,1,Condition) of
                {_,W}->
                    make_weights(Type,SubType,T,[{W,H}|WeightList]);
                _->
                    make_weights(Type,SubType,T,WeightList)
            end;
        _->
            make_weights(Type,SubType,T,WeightList)
    end.

brocast_awards(RName,Type,Grade,Awards)->
    case lib_custom_act_util:get_act_reward_cfg_info(Type,1,Grade) of
        #custom_act_reward_cfg{condition=Condition}->
            case lists:keyfind(tv_show,1,Condition) of
                {_,1}->
                    Id = case Type of
                        ?CUSTOM_ACT_TYPE_LUCKY_BAG1->
                            10;
                        ?CUSTOM_ACT_TYPE_LUCKY_BAG2->
                            27
                    end,
                    [lib_chat:send_TV({all},?MOD_AC_CUSTOM,Id,[RName,GoodsID,Num])||{_,GoodsID,Num}<-Awards];
                _->
                    skip
            end;
        _->
            skip
    end.
