%% ---------------------------------------------------------------------------
%% @doc lib_red_envelopes.erl
%% @author  zengzy
%% @since  2018-06-14
%% @deprecated 公会红包
%% ---------------------------------------------------------------------------
-module(lib_red_envelopes).

-include("figure.hrl").
-include("server.hrl").
-include("red_envelopes.hrl").
-include("def_module.hrl").
-include("def_id_create.hrl").
-include("def_fun.hrl").
-include("def_event.hrl").
-include("rec_event.hrl").
-include("guild.hrl").
-include("sql_guild.hrl").
-include("goods.hrl").
-include("vip.hrl").
-include("common.hrl").
-include("custom_act.hrl").
-include("def_goods.hrl").

-export([
    handle_event/2
    , trigger_red_envelopes/3
    , trigger_red_envelopes/4
    , guild_bonfire_trigger_red_envelopes/2
    , check_red_envelopes_times/4
    , count_obtain_money/1
    , count_money_type/2
    , notify_client/2
    , is_vaild_red_envelopes/1
    , is_vaild_red_envelopes/2
    , pack_red_envelopes_list/2
    , pack_recipients_record/1
    , send_error_code/2
    , send_error_code_by_uid/2
    , get_red_envelopes_classify/1
    , is_act_red_envelopes/1
    , refresh_and_send_reward/3
    , get_rand_money_list/3
    , get_guild_online_num/2
    , get_online_num/2
    , send_got_num/1                %%推送已领取红包金额
    , gm_red/2
    ]).

gm_red(Status,TodayRecharge)->
    trigger_red_envelopes(Status, ?RED_ENVELOPES_TYPE_RECHARGE, [{today_recharge, TodayRecharge}]),
    {ok,Status}.

handle_event(Player, #event_callback{type_id = ?EVENT_RECHARGE}) when is_record(Player, player_status) ->
    TodayRecharge = lib_recharge_api:get_today_pay_gold(Player#player_status.id),
    trigger_red_envelopes(Player, ?RED_ENVELOPES_TYPE_RECHARGE, [{today_recharge, TodayRecharge}]),
    {ok, Player};
handle_event(Player, #event_callback{type_id = ?EVENT_VIP, data=_Data}) when is_record(Player, player_status) ->
    {ok, Player};
handle_event(Player, _) -> {ok, Player}.

% 自动触发系统红包(推荐)
trigger_red_envelopes(Player, Type, Args) ->
    trigger_red_envelopes(Player, Type, ?NO_SEND, Args).

trigger_red_envelopes(Player, Type, RedState, Args)->
    Ids = lib_red_envelopes_check:check_red_packet_ready(Player, Type, Args),
    do_trigger_red_envelopes(Player,RedState,Ids).

do_trigger_red_envelopes(_Player,_RedState, []) -> ok;
do_trigger_red_envelopes(Player,RedState,[Id|T]) ->
    #player_status{id = RoleId, guild = GuildStatus} = Player,
    #status_guild{id = GuildId, lv=GuildLv} = GuildStatus,
    #base_red_envelopes_cfg{type=Type, money=Money, num=Num} = data_red_envelopes:get_envelope(Id),
    MoneyList = get_rand_money_list(Money, Num, ?FULL_MONEY_TYPE),
    Args = [Type, ?GUILD_RED_ENVELOPES, GuildId, RoleId, RedState, Money, MoneyList, Num, Id, GuildLv, "", []],
    mod_red_envelopes:add_red_envelopes(Args),
    do_trigger_red_envelopes(Player,RedState,T).

%% 公会篝火触发红包
guild_bonfire_trigger_red_envelopes(Player, {BossId, ShareList, Money}) ->
    GuildBonfireIds = data_red_envelopes:get_guild_bonfire_ids(),
    case lists:member(BossId, GuildBonfireIds) of
        true->
            Num = length(ShareList),
            #player_status{id = RoleId, guild = GuildStatus} = Player,
            #status_guild{id = GuildId, lv=GuildLv} = GuildStatus,
            MoneyList = get_rand_money_list(Money, Num, ?FULL_MONEY_TYPE),
            Args = [?RED_ENVELOPES_TYPE_BONFIRE, ?GUILD_RED_ENVELOPES, GuildId, RoleId, ?HAS_SEND, Money, MoneyList, Num, BossId, GuildLv, "", ShareList],
            mod_red_envelopes:add_red_envelopes(Args);
        false-> ok
    end.

%%分配好每个红包份额
get_rand_money_list(_Money, 0, _Type) -> [];
get_rand_money_list(Money, 1, _Type) -> [Money];
get_rand_money_list(Money, Num, Type) ->
    case data_guild:get(guild_red_packet_rand) of
        {RandMin, RandMax} -> RandRatio = urand:rand(RandMin, RandMax);
        _ -> RandRatio = 1
    end,
    FirstMoney = urand:rand(1, round(Money/Num*RandRatio)),
    get_rand_money(Num-1, Money-FirstMoney, [FirstMoney], Type).

get_rand_money(0, Money, [LastMoney| T], ?FULL_MONEY_TYPE)->
    NewLastMoney = LastMoney + Money,
    [NewLastMoney| T];
get_rand_money(0, _Money, MoneyList, _Type)->MoneyList;
get_rand_money(Num, Money, MoneyList, Type)->
    RandMoney = urand:rand(1, round(Money/Num)),
    get_rand_money(Num-1, max(Money-RandMoney, 0), [RandMoney|MoneyList], Type).

% 检测红包剩余发送次数
check_red_envelopes_times(Classify, Sub, RoleId, GoodsTypeId) ->
    if
        Classify =:= ?GOODS_RED_ENVELOPES ->
            Count = lib_daily:get_count(RoleId, ?MOD_RED_ENVELOPES, Sub, GoodsTypeId),
            TotalTimes = lib_red_envelopes_data:get_times_limit(?MOD_RED_ENVELOPES_GOODS, GoodsTypeId),
            TotalTimes == 0 orelse TotalTimes - Count > 0;
        true -> true
    end.
%% 物品红包可能有铜币,钻石,绑钻
% count_money_type(?SYSTEM_RED_ENVELOPES, _PacketId) -> ?TYPE_BGOLD;
% count_money_type(?VIP_RED_ENVELOPES, _PacketId) -> ?TYPE_GOLD;
% count_money_type(?GUILD_BONFIER_ENVELOPES, _PacketId) -> ?TYPE_BGOLD;
% count_money_type(?GOODS_RED_ENVELOPES, _GoodsTypeId) -> ?TYPE_BGOLD;
count_money_type(_,PacketId) ->
    case data_red_envelopes:get_envelope(PacketId) of
        #base_red_envelopes_cfg{kind=Kind}->
            ingore;
        _->
            Kind = ?TYPE_BGOLD
    end,
    Kind.

%% 计算领取金额
count_obtain_money(RedEnvelopes) ->
    #red_envelopes{
        money = _Money, split_num = _SplitNum, money_list=MoneyList,
        recipients_num = _RecipientsNum, recipients_lists = _RecipientsList
    } = RedEnvelopes,
    if
        MoneyList == [] -> {0,MoneyList};
        true->
            N = urand:list_rand(MoneyList),
            LeftMoneyList = MoneyList -- [N],
            {N, LeftMoneyList}
    end.

%% 通知客户端
notify_client(?NEW_RED_ENVELOPES, RedEnvelopes) ->
    #red_envelopes{
        ownership_id = OwnershipId, owner_id = OwnerId,
        ownership_type = OwnershipType, status = Status,
        type = Type, packet_id = PacketId
    } = RedEnvelopes,
    case Status of
        ?HAS_SEND ->
            case OwnershipType of
                ?GUILD_RED_ENVELOPES ->
                    RedEnvelopeName = get_name(Type, PacketId),
                    OwnerFigure = lib_role:get_role_figure(OwnerId),
                    %% 发送发红包传闻
                    lib_chat:send_TV({guild, OwnershipId}, ?MOD_RED_ENVELOPES, 1, [OwnerFigure#figure.name, RedEnvelopeName]),
                    {ok, TipsBin} = pt_110:write(11016, [?MOD_RED_ENVELOPES, 1, 1]),
                    lib_server_send:send_to_guild(OwnershipId, TipsBin);
                ?ACT_RED_ENVELOPES ->
                    %% 发送发红包传闻
                    OwnerFigure = lib_role:get_role_figure(OwnerId),
                    lib_chat:send_TV({all}, OwnerId, OwnerFigure, ?MOD_RED_ENVELOPES, 2, []),
                    {ok, BinData} = pt_331:write(33155, [1]),
                    lib_server_send:send_to_all(BinData);
                _ -> skip
            end;
        ?NO_SEND ->
            case OwnershipType of
                ?GUILD_RED_ENVELOPES ->
                    {ok, TipsBin} = pt_110:write(11016, [?MOD_RED_ENVELOPES, 1, 1]),
                    lib_server_send:send_to_uid(OwnerId, TipsBin);
                _ -> skip
            end;
        _ -> skip
    end.

%%获取红包名字
get_name(?RED_ENVELOPES_TYPE_GOODS, PacketId) ->
    case data_red_envelopes:get_goods_cfg(PacketId) of
        #red_envelopes_goods_cfg{name = Name} -> Name;
        _ -> ""
    end;
get_name(?RED_ENVELOPES_TYPE_VIP_PLAYER_SEND, PacketId) ->
    case data_red_envelopes:get_vip(PacketId) of
        #base_vip_red_envelopes_cfg{name = Name} -> Name;
        _ -> ""
    end;
get_name(?RED_ENVELOPES_TYPE_BONFIRE, PacketId) ->
    data_red_envelopes:get_bonfire_name(PacketId);
get_name(_Type, PacketId) ->
    case data_red_envelopes:get_envelope(PacketId) of
        #base_red_envelopes_cfg{name = Name} -> Name;
        _ -> ""
    end.

is_vaild_red_envelopes(RedEnvelopes) ->
    NowTime = utime:unixtime(),
    is_vaild_red_envelopes(RedEnvelopes, NowTime).

is_vaild_red_envelopes(RedEnvelopes, NowTime) when is_record(RedEnvelopes, red_envelopes) ->
    #red_envelopes{type=Type, status = Status, stime = Stime, packet_id=PacketId} = RedEnvelopes,
    case get_red_envelopes_classify(Type) of
        ?GOODS_RED_ENVELOPES ->
            case data_red_envelopes:get_goods_cfg(PacketId) of
                #red_envelopes_goods_cfg{} ->
                    Status == ?NO_SEND orelse (Status =/= ?NO_SEND andalso NowTime < Stime + ?DEL_AF_SEND_TIME);
                _ -> false
            end;
        ?VIP_RED_ENVELOPES ->
            case data_red_envelopes:get_vip(PacketId) of
                #base_vip_red_envelopes_cfg{} ->
                    Status == ?NO_SEND orelse (Status =/= ?NO_SEND andalso NowTime < Stime + ?DEL_AF_SEND_TIME);
                _ -> false
            end;
        ?GUILD_BONFIER_ENVELOPES ->
            BonfireIds = data_red_envelopes:get_guild_bonfire_ids(),
            case lists:member(PacketId, BonfireIds) of
                true ->
                    Status == ?NO_SEND orelse (Status =/= ?NO_SEND andalso NowTime < Stime + ?DEL_AF_SEND_TIME);
                _ -> false
            end;
        _ ->
            case data_red_envelopes:get_envelope(PacketId) of
                #base_red_envelopes_cfg{} ->
                    Status == ?NO_SEND orelse (Status =/= ?NO_SEND andalso NowTime < Stime + ?DEL_AF_SEND_TIME);
                _ -> false
            end
    end;
is_vaild_red_envelopes(_, _) -> false.

get_red_envelopes_classify(Type) ->
    case Type of
        ?RED_ENVELOPES_TYPE_GOODS ->
            ?GOODS_RED_ENVELOPES;
        ?RED_ENVELOPES_TYPE_VIP_PLAYER_SEND ->
            ?VIP_RED_ENVELOPES;
        ?RED_ENVELOPES_TYPE_BONFIRE ->
            ?GUILD_BONFIER_ENVELOPES;
        _ -> ?SYSTEM_RED_ENVELOPES
    end.

%% 是否是活动红包
is_act_red_envelopes(GoodsTypeId) ->
    case data_red_envelopes:get_goods_cfg(GoodsTypeId) of
        #red_envelopes_goods_cfg{ownership_type = ?ACT_RED_ENVELOPES} ->
            case lib_custom_act_api:get_open_custom_act_infos(?CUSTOM_ACT_TYPE_RED_ENVELOPES) of
                [#act_info{etime = Etime}|_] -> {true, Etime};
                _ -> %% 活动红包的时候活动关闭了，自动设置红包为过期
                    {false, 946656000}
            end;
        _ -> {false, 0}
    end.

%% 打包红包列表
pack_red_envelopes_list(RoleId, RedEnvelopesList) ->
    NowTime = utime:unixtime(),
    F = fun(RedEnvelopes, AccList) ->
        case is_vaild_red_envelopes(RedEnvelopes, NowTime) of
            true ->
                #red_envelopes{
                    id = Id, owner_id = OwnerId, type = Type, packet_id = PacKetId,
                    has_look_lists = HasLookList, status = Status
                } = RedEnvelopes,
                #figure{
                    name = OwnerName, career = OwnerCareer, sex = OwnerSex,
                    picture = OwnerPic, picture_ver = OwnerPicVer, turn = OwnerTurn,
                    profile_photo_id = Photo
                } = Figure = lib_role:get_role_figure(OwnerId),
                FrameId = lib_dress_up:get_role_frame_dress(Figure),
                %%获取领取状态和领取金额
                case Status == ?HAS_SEND orelse Status == ?END of
                    true ->
                        {ReceiveStatus, ReceiveNum} = receive_status_and_num(RoleId, Type, RedEnvelopes);
                    false -> ReceiveStatus = ?CAN_RECEIVE, ReceiveNum = 0
                end,
                %%特殊红包是否查看状态
                HasLook = ?IF(lists:member(RoleId, HasLookList), 1, 0),
                [{Id, PacKetId, OwnerId, OwnerName, OwnerCareer, OwnerSex, OwnerTurn, OwnerPic, OwnerPicVer,
                    Photo, FrameId, Type, Status, ReceiveStatus, HasLook, ReceiveNum}|AccList];
            false -> AccList
        end
    end,
    lists:foldl(F, [], RedEnvelopesList).

receive_status_and_num(RoleId, ?RED_ENVELOPES_TYPE_BONFIRE, RedEnvelopes) ->
    #red_envelopes{share_list = ShareList, recipients_lists = RecipientsList} = RedEnvelopes,
    case lists:member(RoleId, ShareList) of
        true-> receive_status_and_num_common(RoleId, RecipientsList);
        false -> {?CAN_NOT_RECEIVE, 0}
    end;
receive_status_and_num(RoleId, _Type, RedEnvelopes) ->
    #red_envelopes{recipients_lists = RecipientsList} = RedEnvelopes,
    receive_status_and_num_common(RoleId, RecipientsList).

receive_status_and_num_common(RoleId, RecipientsList) ->
    case lists:keyfind(RoleId, #recipients_record.role_id, RecipientsList) of
        false -> {?CAN_RECEIVE, 0 };
        #recipients_record{money = ReceiveNum} -> {?HAS_RECEIVE, ReceiveNum};
        _ -> {?HAS_RECEIVE, 0}
    end.

%% 打包红包领取记录
pack_recipients_record(RecipientsRecord) ->
    F = fun(Record, AccList) when is_record(Record, recipients_record) ->
            #recipients_record{role_id = RoleId, money = Money, time = Time} = Record,
            #figure{
                name = RoleName, career = Career, sex = Sex, turn = Turn,
                picture = Picture, picture_ver = PictureVer
            } = lib_role:get_role_figure(RoleId),
            [{RoleId, RoleName, Career, Sex, Turn, Picture, PictureVer, Money, Time}|AccList];
        (_Record, AccList) -> AccList
    end,
    lists:foldl(F, [], RecipientsRecord).

%% 发送错误码
send_error_code(Sid, ErrorCode) ->
    {ok, BinData} = pt_339:write(33900, [ErrorCode]),
    lib_server_send:send_to_sid(Sid, BinData).

%% 发送错误码
send_error_code_by_uid(RoleId, ErrorCode) ->
    {ok, BinData} = pt_339:write(33900, [ErrorCode]),
    lib_server_send:send_to_uid(RoleId, BinData).

%% 获得红包金额和刷新每日金额
refresh_and_send_reward(PS, ?TYPE_BGOLD, Bgold) ->
    #player_status{id=RoleId, guild=StatuGuild} = PS,
    #status_guild{red_packet=OVal, red_gold_packet = GoldVal} = StatuGuild,
    NewVal = OVal + Bgold,
    Sql = io_lib:format(?sql_guild_update_red_packet, [NewVal, GoldVal, RoleId]),
    db:execute(Sql),
    Reward = [{?TYPE_BGOLD, 0, Bgold}],
    Produce = #produce{reward=Reward, type=red_envelopes, show_tips=3},
    NewPS = lib_goods_api:send_reward(PS, Produce),
    NewStatuGuild = StatuGuild#status_guild{red_packet = NewVal},
    NewPS#player_status{guild = NewStatuGuild};
refresh_and_send_reward(PS, ?TYPE_GOLD, Gold) ->
    #player_status{id=RoleId, guild=StatuGuild} = PS,
    #status_guild{red_packet = BGoldVal, red_gold_packet=OGoldVal} = StatuGuild,
    NewVal = OGoldVal + Gold,
    Sql = io_lib:format(?sql_guild_update_red_packet, [BGoldVal, NewVal, RoleId]),
    db:execute(Sql),
    Reward = [{?TYPE_GOLD, 0, Gold}],
    Produce = #produce{reward=Reward, type=red_envelopes, show_tips=3},
    NewPS = lib_goods_api:send_reward(PS, Produce),
    NewStatuGuild = StatuGuild#status_guild{red_gold_packet = NewVal},
    NewPS#player_status{guild = NewStatuGuild};
refresh_and_send_reward(PS, MoneyType, Gold) ->
    Reward = [{MoneyType, 0, Gold}],
    Produce = #produce{reward=Reward, type=red_envelopes, show_tips=3},
    NewPS = lib_goods_api:send_reward(PS, Produce),
    NewPS.

%% 获取公会在线人数
get_guild_online_num(PS, GuildId) ->
    #player_status{id = RoleId} = PS,
    mod_guild:apply_cast(?MODULE, get_online_num, [RoleId, GuildId]).

get_online_num(RoleId, GuildId) ->
    OnlineFlag = 1,
    GuildMemberMap = lib_guild_data:match_guild_member({online_flag, GuildId, OnlineFlag}),
    OnlineNum = maps:size(GuildMemberMap),
    {ok, BinData} = pt_339:write(33906, [OnlineNum]),
    lib_server_send:send_to_uid(RoleId, BinData).

send_got_num(PS) ->
    #player_status{sid = Sid, guild = #status_guild{red_packet = BGoldNum, red_gold_packet = GoldNum}} = PS,
    {ok, BinData} = pt_339:write(33907, [GoldNum, BGoldNum]),
    lib_server_send:send_to_sid(Sid, BinData),
    PS.
