%% --------------------------------
%% module:relation_coupon.erl
%% desc  :每日社交票券
%% author:hh
%% time  :19/11/05
%% --------------------------------

-module(relation_coupon).

-include("relationship.hrl").
-include("server.hrl").
-include("def_module.hrl").
-include("errcode.hrl").
-include("predefine.hrl").
-include("counter.hrl").
-include("def_goods.hrl").
-include("common.hrl").
-include("def_fun.hrl").
-include("mate.hrl").
-include("goods.hrl").

-export([
    login/2
    ,get_role_coupon/1
    ,send_role_coupon/3
    ,receive_coupon/3
    ,batch_send_role_coupon/2
    ,batch_receive_coupon/1
    ]).

-export([
    role_get_coupon/3
    ,role_sender_coupon_change/3
    ,daily_reset/1
    ,daily_clear/0

    ,gm_reset/1
    ,role_notify_one_gm_reset/4
    ]).

%% 登录
login(RoleId, Now) ->
    RoleCoupon =
    case db:get_all(?sql_select_role_coupon_list, [RoleId]) of
        CouponL = [_|_] ->
            init_role_social_coupon(RoleId, CouponL);
        _A1 ->
            #role_rela_coupon{id = RoleId}
    end,
    update_coupon(RoleCoupon, Now).


init_role_social_coupon(RoleId, CouponL) ->
    {NewSendList, NewGiftList, NewSendTime, NewGiftTime} =
    lists:foldl(fun([OpRole, CouponType, Type, Status, Time|_], {TempSendList, TempGiftList, TempSendTime, TempGiftTime}) -> 
        if Type == ?RELA_COUPON_SEND ->
                NewTempSendTime = ?IF(Time > TempSendTime, Time, TempSendTime),
                {[{{OpRole, CouponType}, Time}|TempSendList], TempGiftList, NewTempSendTime, TempGiftTime};
            Type == ?RELA_COUPON_GIFT ->
                NewTempGiftTime = ?IF(Time > TempGiftTime, Time, TempGiftTime),
                {TempSendList, [{{OpRole, CouponType}, Status, Time}|TempGiftList], TempSendTime, NewTempGiftTime};
            true ->
                {TempSendList, TempGiftList, TempSendTime, TempGiftTime}
        end
    end, {[], [], 0, 0}, CouponL),
    #role_rela_coupon{
        id = RoleId, send_list = NewSendList, gift_list = NewGiftList,
        send_time = NewSendTime, gift_time = NewGiftTime
    }.

daily_reset(Player) ->
    #player_status{role_coupon = RoleCoupon} = Player,
    NewRoleCoupon = update_coupon(RoleCoupon, utime:unixtime()),
    Player1 = Player#player_status{role_coupon = NewRoleCoupon},
    get_role_coupon(Player1),
    Player1.

daily_clear() ->
    db:execute(?sql_truncate_role_coupon_list, []),
    ok.

gm_reset(Player) ->
    #player_status{id = RoleId, role_coupon = RoleCoupon} = Player,
    Now = utime:unixtime(),
    NewRoleCoupon0 = check_coupon_update(send_time, RoleCoupon, utime:unixdate()-1, Now),
    NewRoleCoupon1 = check_coupon_update(gift_time, NewRoleCoupon0, utime:unixdate()-1, Now),
    gm_notify_reset(RoleCoupon),
    % db_update_coupon(NewRoleCoupon1),
    db:execute(<<"delete from role_coupon_list where role_id = ~p">>, [RoleId]),
    NewPlayer = Player#player_status{role_coupon = NewRoleCoupon1},
    get_role_coupon(NewPlayer),
    NewPlayer.

gm_notify_reset(RoleCoupon) ->
    #role_rela_coupon{id = RoleId, send_list = SendList, gift_list = GiftList} = RoleCoupon,
    notify_gifter(RoleId, SendList),
    notify_sender(RoleId, GiftList),
    ok.

notify_gifter(RoleId, SendList) ->
    [notify_one_gm_reset(RoleId, gifter, RoleIdX, Type)  || {{RoleIdX, Type}, _} <- SendList].

notify_sender(RoleId, GiftList) ->
    [notify_one_gm_reset(RoleId, sender, RoleIdX, Type) || {{RoleIdX, Type}, _, _} <- GiftList].

notify_one_gm_reset(GmRoleId, RoleType, RoleId, Type) ->
    Pid = misc:get_player_process(RoleId),
    % ?ERR("~p ~p ~p", [GmRoleId, RoleType, RoleId]),
    case is_pid(Pid) andalso misc:is_process_alive(Pid) of
        true ->
            lib_player:apply_cast(Pid, ?APPLY_CAST_STATUS, ?MODULE, role_notify_one_gm_reset, [GmRoleId, RoleType, Type]);
        _ ->
            % #role_rela_coupon{send_list = SendList, gift_list = GiftList} = login(RoleId, utime:unixtime()),
            % if RoleType == gifter -> %% 做为收礼一方
            %         NewGiftList = lists:keydelete({GmRoleId, Type}, 1, GiftList),
            %         NewSendList = SendList;
            %     RoleType == sender -> %% 做为送礼一方
            %         NewSendList = lists:delete({GmRoleId, Type}, SendList),
            %         NewGiftList = GiftList
            % end,
            db:execute(<<"delete from role_coupon_list where role_id = ~p and op_role = ~p">>, [RoleId, GmRoleId])
            % NewRoleCoupon = RoleCoupon#role_rela_coupon{send_list = NewSendList, gift_list = NewGiftList}
            % db_update_coupon(NewRoleCoupon)
    end.

role_notify_one_gm_reset(Player, GmRoleId, RoleType, Type) ->
    #player_status{id = RoleId, role_coupon = RoleCoupon} = Player,
    #role_rela_coupon{send_list = SendList, gift_list = GiftList} = RoleCoupon,
    if RoleType == gifter -> %% 做为收礼一方
            NewGiftList = lists:keydelete({GmRoleId, Type}, 1, GiftList),
            NewSendList = SendList;
        RoleType == sender -> %% 做为送礼一方
            NewSendList = lists:keydelete({GmRoleId, Type}, 1, SendList),
            NewGiftList = GiftList
    end,
    db:execute(<<"delete from role_coupon_list where role_id = ~p and op_role = ~p">>, [RoleId, GmRoleId]),
    NewRoleCoupon = RoleCoupon#role_rela_coupon{send_list = NewSendList, gift_list = NewGiftList},
    % db_update_coupon(NewRoleCoupon),
    NewPlayer = Player#player_status{role_coupon = NewRoleCoupon},
    get_role_coupon(NewPlayer),
    {ok, NewPlayer}.


update_coupon(RoleCoupon, _Now) ->
    #role_rela_coupon{send_time = SendTime, gift_time = GiftTime} = RoleCoupon,
    NewRoleCoupon0 = check_coupon_update(send_time, RoleCoupon, SendTime, _Now),
    check_coupon_update(gift_time, NewRoleCoupon0, GiftTime, _Now).

check_coupon_update(Type, RoleCoupon, Time, Now) ->
    case utime:is_today(Time) of
        true ->
            RoleCoupon;
        _ ->
            if Time == 0 ->
                    RoleCoupon;
                true ->
                    if Type == send_time ->
                            RoleCoupon#role_rela_coupon{send_list = [], send_time = Now};
                        true ->
                            RoleCoupon#role_rela_coupon{gift_list = [], gift_time = Now}
                    end
            end
    end.

% db_update_coupon(RoleCoupon) ->
%     #role_rela_coupon{
%         id = RoleId,
%         send_list = SendList,
%         gift_list = GiftList
%     } = RoleCoupon,
%     SendList1 = [[RoleId, ToRoleIdX, TypeX, 0, ?RELA_COUPON_SEND, TimeX] || {{ToRoleIdX, TypeX}, TimeX} <- SendList],
%     GiftList1 = [[RoleId, FromIdX, TypeX1, StatusX, ?RELA_COUPON_GIFT, TimeX1] || {{FromIdX, TypeX1}, StatusX, TimeX1} <- GiftList],
%     CouponList = lists:append(SendList1, GiftList1),
%     DataStrList = [util:fmt_bin(?sql_batch_replace_val, [RoleIdX, ToRoleId, Type, Status, SendType, Time]) || [RoleIdX, ToRoleId, Type, Status, SendType, Time] <- CouponList],
%     do_batch_db_update_coupon(DataStrList),
%     ok.

db_update_one_coupon(RoleId, FromId, Type, Status, SendType, Now) ->
    db:execute(?sql_replace_role_coupon_list, [RoleId, FromId, Type, SendType, Status, Now]),
    ok.

batch_db_update_coupon(RoleId, FilterGiftList, Status, SendType, Now) ->
    DataStrList = [util:fmt_bin(?sql_batch_replace_val, [RoleId, FromId, TypeX, SendType, Status, Now]) || {{FromId, TypeX}, _, _} <- FilterGiftList],
    do_batch_db_update_coupon(DataStrList).

do_batch_db_update_coupon(DataStrList = [_|_]) ->
    DataStrAll  = util:join_bitstring(DataStrList, <<",">>),
    SqlReplace  = util:fmt_bin(?sql_batch_replace_role_coupon_list, [DataStrAll]),
    db:execute(SqlReplace);
do_batch_db_update_coupon(_) ->
    ok.

%% 获取票券信息
get_role_coupon(Player) ->
    #player_status{id = RoleId, sid = Sid, role_coupon = RoleCoupon} = Player,
    #role_rela_coupon{
        send_list = SendList, gift_list = GiftList
    } = RoleCoupon,
    [{_, SendCount}|_] = lib_daily:get_count(RoleId, [{?MOD_RELA, ?DEFAULT_SUB_MODULE, ?RELA_COUPON_SEND}]), % {?MOD_RELA, ?DEFAULT_SUB_MODULE, ?RELA_COUPON_GIFT}]),
    SendList1 = [{ToRoleIdX, TypeX} || {{ToRoleIdX, TypeX}, _} <- SendList],
    GiftList1 = [{SendRole, Type, Receive}||{{SendRole, Type}, Receive, _Time} <- GiftList],
    % ?ERR("~p ~p", [SendList, GiftList]),
    {ok, Bin} = pt_140:write(14016, [SendCount, 0, SendList1, GiftList1]),
    lib_server_send:send_to_sid(Sid, Bin),
    ok.

%% 赠送票券
send_role_coupon(Player, ToRoleId, Type) ->
    #player_status{sid = Sid, role_coupon = RoleCoupon} = Player,
    #role_rela_coupon{send_list = SendList} = RoleCoupon,
    Ret =
    case send_check(Player, ToRoleId, SendList, Type) of
        true ->
            send_coupon_to_role(Player, ToRoleId, Type);
        {false, Errcode} ->
            lib_server_send:send_to_sid(Sid, pt_140, 14017, [Errcode, 0, Type]),
            ok
    end,
    case Ret of
        {ok, NewPlayer} -> ok;
        _ -> NewPlayer = Player
    end,
    if
        Type == 1 ->
            {ok, NewPlayer1} = mate_logic:update_take_progress(NewPlayer, [ToRoleId, ?TASK_TYPE_5]),
            {ok, NewPlayer1};
        true ->
            {ok, NewPlayer1} = mate_logic:update_take_progress(NewPlayer, [ToRoleId, ?TASK_TYPE_3]),
            {ok, NewPlayer1}
    end.

receive_coupon(Player, FromId, Type) ->
    #player_status{id = RoleId, sid = Sid, role_coupon = RoleCoupon} = Player,
    #role_rela_coupon{gift_list = GiftList} = RoleCoupon,
    case receive_coupon_check(Player, FromId, GiftList, Type) of
        {true, RewardList, ProduceType} ->
            Now = utime:unixtime(),
            NewStatus = ?COUPON_RECEIVED,
            if Type == ?COUPON_FRIEND ->
                    [AddReputation|_] = RewardList,
                    Produce = #produce{reward = [{?TYPE_HONOUR, 0, AddReputation}], type = ProduceType, remark = "好友赠送"},
                    {ok, NewPlayer} = lib_goods_api:send_reward_with_mail(Player, Produce, ?MOD_RELA);
                true ->
                    NewPlayer = lib_goods_api:send_reward(Player, RewardList, ProduceType)
            end,
            NewGiftList   = lists:keystore({FromId, Type}, 1, GiftList, {{FromId, Type}, NewStatus, Now}),
            NewRoleCoupon = RoleCoupon#role_rela_coupon{gift_list = NewGiftList, gift_time = Now},
            % db_update_coupon(NewRoleCoupon),
            db_update_one_coupon(RoleId, FromId, Type, NewStatus, ?RELA_COUPON_GIFT, Now),
            % Type =:= ?COUPON_FRIEND andalso incre_coupon_count(RoleId, ?RELA_COUPON_GIFT),
            lib_server_send:send_to_sid(Sid, pt_140, 14018, [?SUCCESS, FromId, Type]),
            {ok, NewPlayer#player_status{role_coupon = NewRoleCoupon}};
        {false, Errcode} ->
            lib_server_send:send_to_sid(Sid, pt_140, 14018, [Errcode, FromId, Type])
    end.

batch_send_role_coupon(Player, RoleList) ->
    #player_status{id = RoleId, sid = Sid, role_coupon = RoleCoupon} = Player,
    #role_rela_coupon{send_list = SendList} = RoleCoupon,
    Type = ?COUPON_FRIEND,
    case batch_send_check(Player, RoleList, SendList, Type) of
        {true, FilterSendList} ->
            {Onlines, Offlines} =
            lists:foldl(fun(ToRoleId, {OnlineRoles, OfflineRoles}) -> 
                Pid = misc:get_player_process(ToRoleId),
                case is_pid(Pid) andalso misc:is_process_alive(Pid) of
                    true -> {[ToRoleId|OnlineRoles], OfflineRoles};
                    _    -> {OnlineRoles, [ToRoleId|OfflineRoles]}
                end
            end, {[], []}, FilterSendList),
            NewPlayer = lists:foldl(fun(OfflineId, TempPlayer) -> 
                case db_send_coupon_to_role(OfflineId, TempPlayer, Type) of
                    {ok, NewTempPlayer} -> NewTempPlayer;
                    _ -> TempPlayer
                end
            end, Player, Offlines),
            {ok, NewPlayer2} = mate_logic:update_take_progress(NewPlayer, [0, ?TASK_TYPE_5]),
            spawn(fun() -> 
                online_batch_send_coupon_to_role(Onlines, RoleId, Type)
             end),
            lib_server_send:send_to_sid(Sid, pt_140, 14022, [?SUCCESS]),
            {ok, NewPlayer2};
        {false, Errcode} ->
            lib_server_send:send_to_sid(Sid, pt_140, 14022, [Errcode])
    end.

online_batch_send_coupon_to_role([], _RoleId, _Type) -> ok;
online_batch_send_coupon_to_role([ToRoleId|Rest], RoleId, Type) ->
    timer:sleep(urand:rand(50, 80)),
    lib_player:apply_cast(ToRoleId, ?APPLY_CAST_STATUS, ?MODULE, role_get_coupon, [RoleId, Type]),
    online_batch_send_coupon_to_role(Rest, RoleId, Type).

batch_receive_coupon(Player) ->
    #player_status{id = RoleId, sid = Sid, role_coupon = RoleCoupon} = Player,
    Type = ?COUPON_FRIEND,
    #role_rela_coupon{gift_list = GiftList} = RoleCoupon,
    case batch_receive_coupon_check(Player, Type) of
        {true, FilterGiftList, Reputation} ->
            GiftLen = length(FilterGiftList),
            AddReputation = Reputation*GiftLen,
            Now = utime:unixtime(),
            Status = ?COUPON_RECEIVED,
            SendType = ?RELA_COUPON_GIFT,
            batch_db_update_coupon(RoleId, FilterGiftList, Status, SendType, Now),
            Produce = #produce{reward = [{?TYPE_HONOUR, 0, AddReputation}], type = coupon_reward, remark = "好友赠送"},
            {ok, NewPlayer} = lib_goods_api:send_reward_with_mail(Player, Produce, ?MOD_RELA),
            NewGiftList = lists:foldl(fun({{FromId, TypeX}, _Status, _Time}, TempGiftList) -> 
                NewTempGiftList = lists:keystore({FromId, TypeX}, 1, TempGiftList, {{FromId, TypeX}, Status, Now}),
                NewTempGiftList
            end, GiftList, FilterGiftList),
            NewRoleCoupon = RoleCoupon#role_rela_coupon{gift_list = NewGiftList, gift_time = Now},
            % db_update_coupon(NewRoleCoupon),
            % lib_daily:set_count(RoleId, ?MOD_RELA, ?RELA_COUPON_GIFT, GetCount+GiftLen),
            lib_server_send:send_to_sid(Sid, pt_140, 14023, [?SUCCESS]),
            {ok, NewPlayer#player_status{role_coupon = NewRoleCoupon}};
        {false, Errcode} ->
            lib_server_send:send_to_sid(Sid, pt_140, 14023, [Errcode])
    end.


send_coupon_to_role(Player, ToRoleId, Type) ->
    Pid = misc:get_player_process(ToRoleId),
    case is_pid(Pid) andalso misc:is_process_alive(Pid) of
        true -> %% 对方在线
            lib_player:apply_cast(ToRoleId, ?APPLY_CAST_STATUS, ?MODULE, role_get_coupon, [Player#player_status.id, Type]),
            ok;
        _ -> %% 对方离线
            db_send_coupon_to_role(ToRoleId, Player, Type)
    end.

%% 被赠送者进程
role_get_coupon(Player, FromId, Type) ->
    #player_status{id = RoleId, sid = Sid, role_coupon = RoleCoupon} = Player,
    case get_coupon_check(RoleCoupon, FromId, Type) of
        true ->
            Now = utime:unixtime(),
            Status = ?COUPON_RECEIVING,
            SendType = ?RELA_COUPON_GIFT,
            #role_rela_coupon{gift_list = GiftList} = RoleCoupon,
            NewGiftList = add_gift_role({FromId, Type}, Status, Now, GiftList),
            NewRoleCoupon = RoleCoupon#role_rela_coupon{gift_list = NewGiftList, gift_time = Now},
            db_update_one_coupon(RoleId, FromId, Type, Status, SendType, Now),
            % db_update_coupon(NewRoleCoupon),
            %% 通知自己
            lib_server_send:send_to_sid(Sid, pt_140, 14019, [FromId, Type]),
            %% 通知对方
            notice_sender_coupon_change(FromId, RoleId, Type),
            NewPlayer = Player#player_status{role_coupon = NewRoleCoupon},
            {ok, NewPlayer};
        {false, Errcode} ->
            lib_server_send:send_to_uid(FromId, pt_140, 14017, [Errcode, 0, Type])
    end.

db_send_coupon_to_role(ToRoleId, Player, ?COUPON_MATE) ->
    role_take(Player, ToRoleId, ?COUPON_MATE);

db_send_coupon_to_role(ToRoleId, Player, ?COUPON_FRIEND) ->
    % #player_status{sid = Sid} = Player,
    % {GiftCount, _} = lib_daily:get_count_and_other_from_db(ToRoleId, ?MOD_RELA, ?DEFAULT_SUB_MODULE, ?RELA_COUPON_GIFT),
    % ConfigCount = data_rela:get_rela_value(?COUPON_GIFT_CONF),
    % if GiftCount >= ConfigCount ->
    %         lib_server_send:send_to_sid(Sid, pt_140, 14017, [?ERRCODE(err140_gift_num_limit), 0, ?COUPON_FRIEND]),
    %         ok;
    %     true ->
    role_take(Player, ToRoleId, ?COUPON_FRIEND).
    % end.

role_take(Player, ToRoleId, Type) ->
    #player_status{id = RoleId, sid = Sid} = Player,
    Now = utime:unixtime(),
    Status = ?COUPON_RECEIVING,
    SendType = ?RELA_COUPON_GIFT,
    ToRoleCoupon = login(ToRoleId, Now),
    #role_rela_coupon{gift_list = GiftList} = ToRoleCoupon,
    case lists:keymember({RoleId, Type}, 1, GiftList) of
        true -> %?ERR("~p ~p", [ToRoleId, GiftList]),
            lib_server_send:send_to_sid(Sid, pt_140, 14017, [?ERRCODE(err140_32_repeat_send), 0, Type]),
            ok;
        _ ->
            % NewGiftList = add_gift_role({RoleId, Type}, Status, Now, GiftList),
            % NewToRoleCoupon = ToRoleCoupon#role_rela_coupon{gift_list = NewGiftList, gift_time = Now},
            % db_update_coupon(NewToRoleCoupon),
            db_update_one_coupon(ToRoleId, RoleId, Type, Status, SendType, Now),
            role_sender_coupon_change(Player, ToRoleId, Type)
    end.


notice_sender_coupon_change(FromId, RoleId, Type) ->
    lib_player:apply_cast(FromId, ?APPLY_CAST_STATUS, ?MODULE, role_sender_coupon_change, [RoleId, Type]).

%% 赠送者进程
role_sender_coupon_change(Player, ToRoleId, Type) ->
    #player_status{id = RoleId, sid = Sid, role_coupon = RoleCoupon} = Player,
    #role_rela_coupon{send_list = SendList} = RoleCoupon,
    IsExist = lists:keymember({ToRoleId, Type}, 1, SendList),
    if 
        IsExist -> ok;
        true ->
            Now = utime:unixtime(),
            NewSendList = add_send_role({ToRoleId, Type}, Now, SendList),
            Type =:= ?COUPON_FRIEND andalso SendList =/= NewSendList andalso incre_coupon_count(RoleId, ?RELA_COUPON_SEND),
            Type == ?COUPON_FRIEND andalso contract_task_api:friend_coupon_trigger(RoleId, 1),
            NewRoleCoupon = RoleCoupon#role_rela_coupon{send_list = NewSendList, send_time = utime:unixtime()},
            db_update_one_coupon(RoleId, ToRoleId, Type, 0, ?RELA_COUPON_SEND, Now),
            % db_update_coupon(NewRoleCoupon),
            lib_server_send:send_to_sid(Sid, pt_140, 14017, [?SUCCESS, ToRoleId, Type]),
            NewPlayer = Player#player_status{role_coupon = NewRoleCoupon},
            {ok, NewPlayer}
    end.

add_send_role(Key, Time, SendList) ->
    case lists:keymember(Key, 1, SendList) of
        true -> SendList;
        _    -> [{Key, Time}|SendList]
    end.

add_gift_role(Key, Status, Time, GiftList) ->
    case lists:keyfind(Key, 1, GiftList) of
        {_, _, _Val} -> GiftList;
        _ -> lists:keystore(Key, 1, GiftList, {Key, Status, Time})
    end.

incre_coupon_count(RoleId, CountType) ->
    lib_daily:increment(RoleId, ?MOD_RELA, CountType).

send_check(Player, ToRoleId, SendList, Type) ->
    CheckList = [
        {send_repeat_role, ToRoleId, SendList, Type},
        {daily_send_count, Player#player_status.id, Type},
        {check_relationship, Player, ToRoleId, Type}
    ],
    case do_check(CheckList) of
        true ->
            true;
        {false, Errcode} ->
            {false, Errcode}
    end.

batch_send_check(Player, RoleList, SendList, Type) ->
    #player_status{id = RoleId} = Player,
    FilterRoleList = lists:foldl(fun(RoleIdX, Acc) ->
        case lists:keymember({RoleIdX, Type}, 1, SendList) of
            true -> Acc;
            _    -> 
                case lib_relationship_api:get_rela_and_intimacy_online(RoleId, [RoleIdX]) of
                    [{_, ?RELA_TYPE_FRIEND, _}|_] -> [RoleIdX|Acc];
                    _ -> Acc
                end
        end
    end, [], RoleList),
    BatchSendLen = length(FilterRoleList),
    SendCount = lib_daily:get_count(RoleId, ?MOD_RELA, ?RELA_COUPON_SEND),
    ConfigCount = data_rela:get_rela_value(?COUPON_SEND_CONF),
    NewSendCount = BatchSendLen + SendCount,
    if BatchSendLen == 0 ->
            {false, ?ERRCODE(err140_batch_send_error)};
        NewSendCount > ConfigCount ->
            FilterRoleList1 = lists:sublist(FilterRoleList, ConfigCount - SendCount),
            {true, FilterRoleList1};
        true ->
            {true, FilterRoleList}
    end.

batch_receive_coupon_check(Player, Type) ->
    #player_status{id = RoleId, role_coupon = RoleCoupon} = Player,
    #role_rela_coupon{gift_list = GiftList} = RoleCoupon,
    FilterGiftList = lists:foldl(fun(Sender = {{FromId, TypeX}, ReceiveStatus, _Time}, Acc) -> 
        if TypeX == Type andalso ReceiveStatus == ?COUPON_RECEIVING ->
                case lib_relationship_api:get_rela_and_intimacy_online(RoleId, [FromId]) of
                    [{_, ?RELA_TYPE_FRIEND, _}|_] -> [Sender|Acc];
                    _ -> Acc
                end;
            true ->
                Acc
        end
    end, [], GiftList),
    {true, FilterGiftList, 5}.
    % BatchReceiveLen = length(FilterGiftList),
    % GetCount = lib_daily:get_count(RoleId, ?MOD_RELA, ?RELA_COUPON_GIFT),
    % ConfigCount = data_rela:get_rela_value(?COUPON_GIFT_CONF),
    % NewGetCount = BatchReceiveLen + GetCount,
    % if BatchReceiveLen == 0 ->
    %         {false, ?ERRCODE(err140_batch_receive_error)};
    %     NewGetCount > ConfigCount ->
    %         FilterGiftList1 = lists:sublist(FilterGiftList, ConfigCount - GetCount),
    %         {true, FilterGiftList1, GetCount, 5};
    %     true ->
    %         {true, FilterGiftList, GetCount, 5}
    % end.

receive_coupon_check(Player, FromId, GiftList, Type) ->
    CheckList = [
        {receive_repeat_role, FromId, GiftList, Type},
        {daily_get_count, Player#player_status.id, Type},
        {check_relationship, Player, FromId, Type}
    ],
    case do_check(CheckList) of
        true ->
            RewardList  = case Type of
                ?COUPON_FRIEND ->
                    [5];
                ?COUPON_MATE ->
                    [{?TYPE_CURRENCY, ?GOODS_ID_MATE, 1}]
            end,
            ProduceType = coupon_reward,
            {true, RewardList, ProduceType};
        {false, Errcode} ->
            {false, Errcode}
    end.

get_coupon_check(RoleCoupon, FromId, Type) ->
    CheckList = [
        {gift_from_role, FromId, RoleCoupon#role_rela_coupon.gift_list, Type},
        {daily_get_count, RoleCoupon#role_rela_coupon.id, Type}
    ],
    case do_check(CheckList) of
        true ->
            true;
        {false, Errcode} ->
            {false, Errcode}
    end.

do_check([]) -> true;
do_check([{send_repeat_role, ToRoleId, SendList, Type}|Rest]) ->
    case lists:keymember({ToRoleId, Type}, 1, SendList) of
        false ->
            do_check(Rest);
        true ->
            {false, ?ERRCODE(err140_32_repeat_send)}
    end;
do_check([{gift_from_role, RoleId, GiftList, Type}|Rest]) ->
    case lists:keymember({RoleId, Type}, 1, GiftList) of
        true ->
            {false, ?ERRCODE(err140_32_repeat_send)};
        _ ->
            do_check(Rest)
    end;
do_check([{daily_send_count, _RoleId, ?COUPON_MATE}|Rest]) ->
    do_check(Rest);
do_check([{daily_send_count, RoleId, ?COUPON_FRIEND}|Rest]) ->
    SendCount = lib_daily:get_count(RoleId, ?MOD_RELA, ?RELA_COUPON_SEND),
    ConfigCount = data_rela:get_rela_value(?COUPON_SEND_CONF),
    if SendCount >= ConfigCount ->
            {false, ?ERRCODE(err140_send_num_limit)};
        true ->
            do_check(Rest)
    end;
do_check([{daily_get_count, _RoleId, ?COUPON_MATE}|Rest]) ->
    do_check(Rest);
do_check([{daily_get_count, RoleId, ?COUPON_FRIEND}|Rest]) ->
    GetCount = lib_daily:get_count(RoleId, ?MOD_RELA, ?RELA_COUPON_GIFT),
    ConfigCount = data_rela:get_rela_value(?COUPON_GIFT_CONF),
    if GetCount >= ConfigCount ->
            {false, ?ERRCODE(err140_gift_num_limit)};
        true ->
            do_check(Rest)
    end;
do_check([{receive_repeat_role, FromId, GiftList, Type}|Rest]) ->
    case lists:keyfind({FromId, Type}, 1, GiftList) of
        false ->
            {false, ?ERRCODE(err140_role_not_send)};
        {_, ?COUPON_RECEIVED, _} ->
            {false, ?ERRCODE(err140_you_have_received)};
        {_, ?COUPON_RECEIVING, _} ->
            do_check(Rest);
        _ ->
            {false, ?FAIL}
    end;
do_check([{check_relationship, Player, ToRoleId, ?COUPON_FRIEND}|Rest]) ->
    [{_, Rela, _Intimacy}] = lib_relationship_api:get_rela_and_intimacy_online(Player#player_status.id, [ToRoleId]),
    case Rela =:= ?RELA_TYPE_FRIEND of
        true  -> do_check(Rest);
        false -> {false, ?ERRCODE(err140_6_not_friend)}
    end;
do_check([{check_relationship, Player, ToRoleId, ?COUPON_MATE}|Rest]) ->
    case mate_api:is_mate(Player, ToRoleId) of
        true  -> do_check(Rest);
        false -> {false, ?ERRCODE(err149_not_mate)}
    end;
do_check([_|Rest]) ->
    do_check(Rest).