%%%--------------------------------------
%%% @Module  : lib_gift_new
%%% @Author  : calvin
%%% @Email   : calvinzhong888@gmail.com
%%% @Created : 2012.7.3
%%% @Description: 礼包相关代码（新版）
%%%--------------------------------------

-module(lib_gift_new).
-include("def_goods.hrl").
-include("goods.hrl").
-include("gift.hrl").
-include("server.hrl").
-include("common.hrl").
-include("sql_goods.hrl").
-include("unite.hrl").
-include("figure.hrl").
-include("def_fun.hrl").
-include("def_module.hrl").
-include("errcode.hrl").
-include("guild.hrl").
-include("predefine.hrl").
-include("local_boss.hrl").
-export ([
          use_gift/6,               %% 在背包中打开礼包
          use_optional_gift/6,      %% 在背包中使用自选礼包
          fetch_gift_in_good/3,     %% 领取礼包的方法
          fetch_gift_in_good/4,     %% 领取礼包的方法
          send_goods_notice_msg/2,	%% 右下角显示获得具体什么物品
          get_gift_info/2           %% 获取礼包内容
         ]).

-export([
         update_to_received/2,      %% 更新礼包为领取状态（修改表并加缓存）
         set_gift_fetch_status/3,   %% 设置礼包领取状态（只加缓存）
         get_gift_fetch_status/2,   %% 获取礼包领取状态
         trigger_fetch/2,           %% 触发达成礼包，但状态为未领取
         trigger_finish/2,          %% 触发达成礼包，状态为已经领取

         merge_helper/3
        ]).

%% 计算礼包内容
-export([calc_gift_goods/3]).

%% 直接调用领取礼包的方法
fetch_gift_in_good(PS, GS, GiftId) ->
    fetch_gift_in_good(PS, GS, GiftId, 1).

fetch_gift_in_good(PS, GS, GiftId, GiftNum) ->
    GiftInfo = data_gift:get(GiftId),
    case lib_gift_check:ckeck_use_gift(PS, GS, GiftInfo, GiftNum) of
        %% 直接领取礼包内物品
        ok when GiftInfo#ets_gift.get_way =:= 1->
            case private_gift_to_package(GS, GiftInfo, GiftNum) of
                {ok, NewGS, GoodsL} ->
                    GiveList = [{?TYPE_GOODS, GiftInfo#ets_gift.goods_id, GiftNum}],
                    {ok, PS, NewGS, GoodsL, GiveList};
                {fail, ErrorCode} ->
                    {fail, ErrorCode}
            end;
        %% 直接领取礼包内物品
        ok ->
            private_gift_to_open_in_goods(PS, GS, GiftInfo, GiftNum);
        {fail, ErrorCode} ->
            {fail, ErrorCode}
    end.

%% 将礼包放进背包，不打开礼包的东西
private_gift_to_package(GS, GiftInfo, GiftNum) ->
    GoodsTypeId = GiftInfo#ets_gift.goods_id,
    case goods_add:give_more_do(GS, [{GoodsTypeId, GiftNum}]) of
        {ok, GoodsStatus, UpdateL} ->
            lib_goods_api:notify_client(GoodsStatus#goods_status.player_id, UpdateL, gift),
            {ok, GoodsStatus, UpdateL};
        {db_error, {error, {_Type, not_found}}} ->
            {fail, ?ERRCODE(err150_no_goods_type)};
        {db_error, {error, {cell_num, not_enough}}} ->
            {fail, ?ERRCODE(err150_no_cell)};
        _ ->
            {fail, ?ERRCODE(err150_gift_fetch_error)}
    end.

%% 直接打开礼包获取里面的物品
private_gift_to_open_in_goods(PS, GS, GiftInfo, GiftNum) ->
    GiftList = calc_gift_goods(PS, GiftInfo, GiftNum),
    GiftList2 = merge_helper(GiftList, [], []),
    F = fun() ->
                ok = lib_goods_dict:start_dict(),
                [_, NewPS, NewGST, _, _, _]
                    = lists:foldl(fun private_give_gift_item/2, [GiftInfo, PS, GS, ?UNBIND, 0, []], GiftList2),
                {Dict, GoodsL} = lib_goods_dict:handle_dict_and_notify(NewGST#goods_status.dict),
                NewGS = NewGST#goods_status{dict = Dict, temp_bag = #{}},
                %% 战魂收集
                Player = warsoul_logic:collect_goods(NewPS, GiftList2),
                {ok, Player, NewGS, GoodsL, GiftList2}
        end,
    case goods_transaction:transaction(F) of
        {ok, LastPS, NewGS, GoodsL, GiftList2} ->
            lib_goods_api:notify_client(NewGS#goods_status.player_id, GoodsL, gift),
            %% 写开礼包日志
            About = pack_get_log_about(GiftList2),
            lib_log_api:log_gift(PS#player_status.id, 0, GiftInfo#ets_gift.goods_id, GiftInfo#ets_gift.goods_id, GiftNum, About),
            lib_log_api:log_goods(pack_log_goods(PS#player_status.id, GiftInfo#ets_gift.goods_id, GiftList2)),
            lib_goods_api:send_tv_tip(PS#player_status.id, GiftList2),
            {ok, LastPS, NewGS, GoodsL, GiftList2};
        Error ->
            Error
    end.

%%-------------------------------------------------------------------
%% @doc 在背包中打开礼包，goods进程会调用该方法,在该方法里面，不能再去调用goods进程的方法 游戏线
%% use_gift(PS, GS, GoodsInfo, GiftInfo, GoodsNum) ->
%%     {NewPS, NewGS, NewGoodsNum, GiveList} | {fail,Error}
%%----------------------------------------------------------------------------------
use_gift(PS, GS, GoodsInfo, GiftInfo, GoodsNum, Cost) ->
    F = fun() ->
                ok = lib_goods_dict:start_dict(),
                %% 先删除本礼包
                [NewStatus, _] = goods_del:delete_one(GoodsInfo,[GS, GoodsNum]),
                %% 删除消耗
                {true, NewGS, NewPS} = lib_goods_util:cost_object_list(PS, Cost, use_gift, integer_to_list(GoodsInfo#goods.goods_id), NewStatus),
                %% 计算礼包奖励
                NewNum = GoodsInfo#goods.num - GoodsNum,
                GiftList = calc_gift_goods(PS, GiftInfo, GoodsNum),
                GiftList2 = merge_helper(GiftList, [], []),
                [_, NewPs, NewGs, _, _, _] =
                    lists:foldl(fun private_give_gift_item/2, [GiftInfo, NewPS, NewGS, GoodsInfo#goods.bind, 0, []], GiftList2),
                update_to_received(PS#player_status.id, GiftInfo#ets_gift.goods_id),
                {D, GoodsL} = lib_goods_dict:handle_dict_and_notify(NewGs#goods_status.dict),
                lib_player:apply_cast(PS#player_status.id, ?APPLY_CAST_STATUS, ?NOT_HAND_OFFLINE, lib_goods_api, after_send_reward, [GiftList2]),
                %% 战魂收集
                Player = warsoul_logic:collect_goods(NewPs, GiftList2),
                {ok, Player, NewGs#goods_status{dict = D, temp_bag = #{}}, NewNum, GiftList2, GoodsL}
        end,
    case goods_transaction:transaction(F) of
        {ok, LastNewPS, LastNewGoodsStatus1, LastNewNum, LastGiveList, UpdateGoodsList} ->
            %% 礼包使用日志
            About = pack_get_log_about(LastGiveList),
            lib_log_api:log_gift(PS#player_status.id, GoodsInfo#goods.id, GiftInfo#ets_gift.goods_id, GiftInfo#ets_gift.goods_id, GoodsNum, About),
            lib_log_api:log_goods(pack_log_goods(PS#player_status.id, GiftInfo#ets_gift.goods_id, LastGiveList)),
            %% 记录开启次数
            case lists:keyfind(count, 1, GiftInfo#ets_gift.condition) of
                false -> skip;
                {count, _Count} -> lib_daily:plus_count(PS#player_status.id, ?MOD_GOODS, ?MOD_GOODS_GIFT, GiftInfo#ets_gift.goods_id, GoodsNum)
            end,
            lib_goods_api:notify_client(LastNewPS, UpdateGoodsList, gift),
            %% 礼包传闻
            private_get_valuable_send_tv(LastNewPS, GiftInfo, UpdateGoodsList),
            lib_goods_api:send_tv_tip(PS#player_status.id,LastGiveList),
            lib_vie_rank:update_role_vie(LastGiveList,LastNewPS),
            {ok, LastNewPS, LastNewGoodsStatus1, LastNewNum, LastGiveList};
        Err ->
            {fail, Err}
    end.

%% 获取自选宝箱物品内容
%% Num:玩家使用的礼包数量
%% SeqList:内容序号
use_optional_gift(PS, GoodsStatus, GoodsInfo, _OptionalGift, GoodsList, Num) ->
    F = fun() ->
                ok = lib_goods_dict:start_dict(),
                %% 先删除自选宝箱
                [NewGS, _] = goods_del:delete_one(GoodsInfo, [GoodsStatus, Num]),
                %% 发送物品
                [_, _, NewPS, NewGs, _, GiveList]
                    = lists:foldl(fun give_reward_item/2, [optional_gift, GoodsInfo#goods.goods_id, PS,
                                                           NewGS, GoodsInfo#goods.bind, []],
                                  GoodsList),
                {D, GoodsL} = lib_goods_dict:handle_dict_and_notify(NewGs#goods_status.dict),
                WarSoulCollectPS = warsoul_logic:collect_goods(NewPS, GoodsList),
                {ok, WarSoulCollectPS, NewGs#goods_status{dict = D, temp_bag = #{}}, GoodsL, GiveList}
        end,
    case goods_transaction:transaction(F) of
        {ok, LastNewPS, LastNewGoodsStatus, UpdateGoodsList, TipGiveList} ->
            %% 发送获得物品信息给客户端显示在右下角
            lib_gift_new:send_goods_notice_msg(PS, TipGiveList),
            %% 写开等级礼包日志
            About = pack_get_log_about(TipGiveList),
            lib_log_api:log_gift(PS#player_status.id, GoodsInfo#goods.id, GoodsInfo#goods.goods_id, GoodsInfo#goods.goods_id, Num, About),
            lib_log_api:log_goods(pack_log_goods(PS#player_status.id, GoodsInfo#goods.goods_id, TipGiveList)),
            lib_goods_api:notify_client(LastNewPS, UpdateGoodsList, gift),
            lib_goods_do:set_goods_status(LastNewGoodsStatus),
            {ok, ?SUCCESS, LastNewPS};
        _Err->
            {fail, ?FAIL, _Err}
    end.

%% ================================= private fun =================================
%% 整理合并列表
merge_helper([{Type = ?TYPE_GOODS, GoodsTypeId, GoodsNum}| GiftList], GoodsList, Save) ->
    NewGoodsList = case lists:keyfind({Type, GoodsTypeId}, 1, GoodsList) of
                       {_, Num} -> [{ {Type, GoodsTypeId}, GoodsNum+Num}| lists:keydelete({Type, GoodsTypeId}, 1, GoodsList)];
                       false    -> [{ {Type, GoodsTypeId}, GoodsNum} | GoodsList]
                   end,
    merge_helper(GiftList, NewGoodsList, Save);
merge_helper([{Type = ?TYPE_BIND_GOODS, GoodsTypeId, GoodsNum}| GiftList], GoodsList, Save) ->
    NewGoodsList = case lists:keyfind({Type, GoodsTypeId}, 1, GoodsList) of
                       {_, Num} -> [{ {Type, GoodsTypeId}, GoodsNum+Num}| lists:keydelete({Type, GoodsTypeId}, 1, GoodsList)];
                       false    -> [{ {Type, GoodsTypeId}, GoodsNum} | GoodsList]
                   end,
    merge_helper(GiftList, NewGoodsList, Save);
merge_helper([H | GiftList], GoodsList, Save) ->
    merge_helper(GiftList, GoodsList, [H|Save]);
merge_helper([], GoodsList, Save) ->
    F = fun ({ {?TYPE_GOODS, GoodsTypeId}, GoodsNum}) -> {?TYPE_GOODS, GoodsTypeId, GoodsNum};
            ({ {?TYPE_BIND_GOODS, GoodsTypeId}, GoodsNum}) -> {?TYPE_BIND_GOODS, GoodsTypeId, GoodsNum};
            ({ {?TYPE_ATTR_GOODS, GoodsTypeId}, GoodsNum, _Args}) -> {?TYPE_GOODS,GoodsTypeId,GoodsNum}
        end,
    GoodsList2 = lists:map(F, GoodsList),
    GoodsList2 ++ Save.

%% 具体处理礼包配置的各种属性奖励或物品奖励
%% IsFetchGoods	该项值只针对物品或者装备，对其他配的没影响。值0：会获取物品和装备  1：不会获取物品和装备  2：不会获取装备
private_give_gift_item(Item, [GiftInfo, PlayerStatus, GoodsStatus, Bind, IsFetchGoods, GoodsList]) ->
    case Item of
        {?TYPE_GOODS, GoodsTypeId, GoodsNum} -> %% 物品
            if
                IsFetchGoods =:= 0 ->
                    {ok, NewStatus} = goods_add:give_goods({GoodsTypeId, GoodsNum}, GoodsStatus),
                    [GiftInfo, PlayerStatus, NewStatus, Bind, IsFetchGoods, GoodsList];
                IsFetchGoods =:= 2 ->
                    {ok, NewStatus} = goods_add:give_goods({GoodsTypeId, GoodsNum}, GoodsStatus),
                    [GiftInfo, PlayerStatus, NewStatus, Bind, IsFetchGoods, GoodsList];
                true ->
                    NewStatus = GoodsStatus,
                    [GiftInfo, PlayerStatus, NewStatus, Bind, IsFetchGoods, [Item|GoodsList]]
            end;
        {?TYPE_BIND_GOODS, GoodsTypeId, GoodsNum} -> %% 绑定物品
            if
                IsFetchGoods =:= 0 ->
                    {ok, NewStatus} = goods_add:give_goods({goods, GoodsTypeId, GoodsNum, ?BIND}, GoodsStatus),
                    [GiftInfo, PlayerStatus, NewStatus, Bind, IsFetchGoods, GoodsList];
                IsFetchGoods =:= 2 ->
                    {ok, NewStatus} = goods_add:give_goods({goods, GoodsTypeId, GoodsNum, ?BIND}, GoodsStatus),
                    [GiftInfo, PlayerStatus, NewStatus, Bind, IsFetchGoods, GoodsList];
                true ->
                    NewStatus = GoodsStatus,
                    [GiftInfo, PlayerStatus, NewStatus, Bind, IsFetchGoods, [Item|GoodsList]]
            end;
        Currency ->
	        %% 名望券礼包不限制使用,其他途径限制使用
	        case Currency of
		        {?TYPE_HONOUR, _GoodsTypeId, _GoodsNum} ->
					NewPlayer = goods_add:send_reward_currency(PlayerStatus, Currency, honour_not_limit, lists:concat(["GiftId=", GiftInfo#ets_gift.goods_id]));
				_ ->
					NewPlayer = goods_add:send_reward_currency(PlayerStatus, Currency, gift, lists:concat(["GiftId=", GiftInfo#ets_gift.goods_id]))
	        end,
            [GiftInfo, NewPlayer, GoodsStatus, Bind, IsFetchGoods, GoodsList]
    end.


%% 向玩家添加物品列表
give_reward_item(Item, [Type, GoodsId, PlayerStatus, GoodsStatus, Bind, GiveList]) ->
    case Item of
        %% 物品
        {GoodsType, GoodsTypeId, GoodsNum}
            when GoodsType == ?TYPE_GOODS
            orelse GoodsType == ?TYPE_BIND_GOODS ->
            {ok, NewStatus} = goods_add:give_goods({goods, GoodsTypeId, GoodsNum, ?BIND}, GoodsStatus),
            [Type, GoodsId, PlayerStatus, NewStatus, Bind, [Item|GiveList]];
        {?TYPE_ATTR_GOODS, GoodsTypeId, GoodsNum, DyAttrList} ->
            {ok, NewStatus} = goods_add:give_goods({goods_attr, GoodsTypeId, GoodsNum, DyAttrList}, GoodsStatus),
            [Type, GoodsId, PlayerStatus, NewStatus, Bind, [Item|GiveList]];
        Currency ->
            NewPlayer = goods_add:send_reward_currency(PlayerStatus, Currency, gift, lists:concat(["GiftId=", GoodsId])),
            [Type, GoodsId, NewPlayer, GoodsStatus, Bind, Bind, [Item|GiveList]]
    end.

%% 整理日志备注内容
pack_get_log_about(GiftList) ->
    F = fun(Item, List) ->
                case Item of
                    {?TYPE_GOODS, Id, Num} -> [{Id, Num}|List];
                    {?TYPE_BIND_GOODS, Id, Num} -> [{Id, Num}|List];
                    {?TYPE_COIN, _Id, Num} -> [{?GOODS_ID_COIN, Num}|List];
                    {?TYPE_GOLD, _Id, Num} -> [{?GOODS_ID_GOLD, Num}|List];
                    {?TYPE_BGOLD, _Id, Num} -> [{?GOODS_ID_BGOLD, Num}|List];
                    {?TYPE_FGOLD, _Id, Num} -> [{?GOODS_ID_FGOLD, Num}|List];
                    {?TYPE_EXP, _Id, Num} -> [{?GOODS_ID_EXP, Num}|List];
                    {?TYPE_GFUNDS, _Id, Num} -> [{?GOODS_ID_GFUNDS, Num}|List];
                    {?TYPE_GFAME, _Id, Num} -> [{?GOODS_ID_GFAME, Num}|List];
                    {?TYPE_HONOUR, _Id, Num} -> [{?GOODS_ID_HONOR, Num}|List];
                    {?TYPE_HI_POINT, _Id, Num} -> [{?GOODS_ID_HI, Num}|List];
                    {?TYPE_WORKROOM, _Id, Num} -> [{?GOODS_ID_FASHION_COIN, Num}|List];
                    {?TYPE_CURRENCY, Id, Num} -> [{Id, Num}|List];
                    _R ->
                        ?ERR("unowkn item type:~p~n", [_R]),
                        List
                end
        end,
    lists:foldl(F, [], GiftList).

pack_log_goods(PlayerId, GiftId, GiftList) ->
    Nowtime = utime:unixtime(),
    TypeId = data_goods:get_produce_type(gift),
    Remark = ulists:concat(["use gift:", GiftId]),
    F = fun(Item, AccList) ->
        case Item of
            {?TYPE_GOODS, GoodsTypeId, GoodsNum} -> skip;
            {?TYPE_BIND_GOODS, GoodsTypeId, GoodsNum} -> skip;
            _ -> GoodsTypeId = 0, GoodsNum =0
        end,
        case GoodsTypeId=/=0 of
            true -> [[Nowtime, TypeId, 0, GoodsTypeId, GoodsNum, PlayerId, Remark]|AccList];
            false -> AccList
        end
    end,
    lists:foldl(F, [], GiftList).

%% ================================= private fun =================================
%% 计算礼包物品
calc_gift_goods(Ps, GiftInfo, Num) ->
    [Lv, Sex, Career, Turn] = lib_gift_check:get_filter_items(GiftInfo#ets_gift.filter, Ps, [0, 0, 0, 0]),
    GiftReward = data_gift:get_gift_reward(GiftInfo#ets_gift.goods_id, Lv, Sex, Career, Turn),
    #ets_gift_reward{fixed_gifts = FixedGifts, is_back = IsBack,
                     rand = Rand, rand_gifts = RandGift, drop_gifts = DropGift} = GiftReward,
    NewFixedGifts = [{Type, GId, GN*Num} || {Type, GId, GN} <- FixedGifts],
    %% 计算掉落规则的物品
    {_, RandDrops} = drop_logic:drop_goods_list(DropGift, Ps#player_status.figure#figure.career),
    RandDropsGoods = drop_logic:ets_drop_to_goods_list(RandDrops),
    calc_rand_goods_nums(RandGift, Rand, IsBack, NewFixedGifts ++ RandDropsGoods, Num).

%% 多次开启
calc_rand_goods_nums(_RandGift, _Rand, _IsBack, Gifts, 0) -> Gifts;
calc_rand_goods_nums(RandGift, Rand, IsBack, Gifts, Num) ->
    NewGifts = calc_rand_goods(RandGift, Rand, IsBack, Gifts),
    calc_rand_goods_nums(RandGift, Rand, IsBack, NewGifts, Num-1).

%% 单次计算礼包的随机物品
calc_rand_goods([], _RandNum, _IsBack, Goods)-> Goods;
calc_rand_goods(_RandGift, 0, _IsBack, Goods)-> Goods;
calc_rand_goods(RandGift, RandNum, IsBack, Goods)->
    TotalRatio = get_ratio_total(RandGift, 2),
    Rand = urand:rand(1, TotalRatio),
    case find_ratio(RandGift, 0, Rand, 2) of
        null ->
            calc_rand_goods(RandGift, RandNum-1, IsBack, Goods);
        {G, _R} = Gift ->
            NewRandGift = ?IF(IsBack == 0, RandGift -- [Gift], RandGift),
            calc_rand_goods(NewRandGift, RandNum-1, IsBack, [G|Goods])
    end.
get_ratio_total(RatioList, N) ->
    F = fun(RatioInfo, Sum) ->
        element(N, RatioInfo) + Sum
        end,
    lists:foldl(F, 0, RatioList).
find_ratio([], _, _, _) -> null;
find_ratio(InfoList, Start, Rand, N) ->
    [Info | List] = InfoList,
    End = Start + element(N, Info),
    case Rand > Start andalso Rand =< End of
        true  -> Info;
        false -> find_ratio(List, End, Rand, N)
    end.
%% 发送获得物品信息给客户端显示在右下角
send_goods_notice_msg(PS, GiveList) ->
    F = fun(Item, Data) ->
                case Item of
                    {?TYPE_GOODS, GoodsTypeId, GoodsNum} ->
                        [{GoodsTypeId, GoodsNum} | Data];
                    {?TYPE_BIND_GOODS, GoodsTypeId, GoodsNum} ->
                        [{GoodsTypeId, GoodsNum} | Data];
                    {?TYPE_GOLD, _GoodsTypeId, GoodsNum} ->
                        [{?GOODS_ID_GOLD, GoodsNum} | Data];
                    {?TYPE_COIN, _GoodsTypeId, GoodsNum} ->
                        [{?GOODS_ID_COIN, GoodsNum} | Data];
                    {?TYPE_EXP, _GoodsTypeId, GoodsNum} ->
                        [{?GOODS_ID_EXP, GoodsNum} | Data];
                    {?TYPE_GFUNDS, _GoodsTypeId, GoodsNum} ->
                        [{?GOODS_ID_GFUNDS, GoodsNum} | Data];
                    {?TYPE_GFAME, _GoodsTypeId, GoodsNum} ->
                        [{?GOODS_ID_GFAME, GoodsNum} | Data];
                    {goods, GoodsTypeId, GoodsNum} ->
                        [{GoodsTypeId, GoodsNum} | Data];
                    {coin, CoinNum} ->
                        CoinId = ?GOODS_ID_COIN,
                        [{CoinId, CoinNum} | Data];
                    {gold, GoldNum} ->
                        GoldId = ?GOODS_ID_GOLD,
                        [{GoldId, GoldNum} | Data];
                    {bgold, GoldNum} ->
                        GoldId = ?GOODS_ID_BGOLD,
                        [{GoldId, GoldNum} | Data];
                    {exp, GoldNum} ->
                        GoldId = ?GOODS_ID_EXP,
                        [{GoldId, GoldNum} | Data];
                    _ ->
                        Data
                end
        end,
    NewList = lists:foldl(F, [], GiveList),
    case length(NewList) > 0 of
        true ->
            Type = 1, % 右下角飘字
            {ok, BinData} = pt_110:write(11060, [Type, NewList]),
            lib_server_send:send_to_sid(PS#player_status.sid, BinData);
        _ ->
            skip
    end.

%% 礼包传闻
private_get_valuable_send_tv(PS, Gift, UpdateGoods) ->
    [Lv, Sex, Career, Turn] = lib_gift_check:get_filter_items(Gift#ets_gift.filter, PS, [0, 0, 0, 0]),
    GiftReward = data_gift:get_gift_reward(Gift#ets_gift.goods_id, Lv, Sex, Career, Turn),
    #ets_gift_reward{tv_goods_id = TvGoodIds} = GiftReward,
    Name = PS#player_status.figure#figure.name,
    send_gift_reward_tv(PS, Name, Gift#ets_gift.goods_id, TvGoodIds, UpdateGoods).

%% 礼包物品传闻
send_gift_reward_tv(_PS, _, _, _, []) -> ok;
send_gift_reward_tv(PS, Name, GiftId, TvGoodIds,
    [#goods{color = Color, type = GoodsType, goods_id = GoodsTypeId}|UpdateGoodsList]) ->
    ta_agent_fire:equip_get(PS, GoodsTypeId, 1),
    case Color >= ?ORANGE andalso GoodsType =:= ?GOODS_TYPE_EQUIP of
        true  ->
            %% 橙色装备，直接给传闻
            Log = #boss_drop_log{
                name = Name
                , boss = GiftId
                , boss_type = 100
                , goods_id = GoodsTypeId
                , time = utime:unixtime()
            },
            reward_boss_mgr:add_reward_boss_drop_log(Log),
            lib_chat:send_TV({all}, ?MOD_GOODS, 1, [Name, GiftId, GoodsTypeId]);
        false ->
            %% 其他的，配置了的才判断
            case lists:member(GoodsTypeId, TvGoodIds) of
                false -> ok;
                true  ->
                    lib_chat:send_TV({all}, ?MOD_GOODS, 1, [Name, GiftId, GoodsTypeId])
            end
    end,
    send_gift_reward_tv(PS, Name, GiftId, TvGoodIds, UpdateGoodsList).

%% 获取礼包领取状态
%% 返回：-1未领取（未插入记录），0未领取（已经插入记录），1已经领取
get_gift_fetch_status(RoleId, GiftId) ->
    CacheKey = ?GIFT_CACHE_KEY(RoleId, GiftId),
    Result = mod_daily_dict:get_special_info(CacheKey),
    case Result of
        undefined ->
            Sql = io_lib:format(?SQL_GIFT_LIST_FETCH_ROW, [RoleId, GiftId]),
            case db:get_row(Sql) of
                [] ->
                    mod_daily_dict:set_special_info(CacheKey, -1),
                    -1;
                [_, _, Status] ->
                    %% Status 0为未领取，1为领取
                    mod_daily_dict:set_special_info(CacheKey, Status),
                    Status
            end;
        Data ->
            Data
    end.

%% 更新礼包为领取状态（修改表并加缓存）
update_to_received(PlayerId, GiftId) ->
    Sql = io_lib:format(?SQL_GIFT_LIST_UPDATE_TO_RECEIVED, [utime:unixtime(), PlayerId, GiftId]),
    db:execute(Sql),
    set_gift_fetch_status(PlayerId, GiftId, 1).

%% 设置礼包领取状态
set_gift_fetch_status(RoleId, GiftId, Status) ->
    mod_daily_dict:set_special_info(?GIFT_CACHE_KEY(RoleId, GiftId), Status).

%% 触发达成礼包，状态为未领取奖励
trigger_fetch(RoleId, GiftId) ->
    Now = utime:unixtime(),
    Sql = io_lib:format(?SQL_GIFT_LIST_INSERT, [RoleId, GiftId, Now, Now, 0, 0]),
    db:execute(Sql),
    mod_daily_dict:set_special_info(?GIFT_CACHE_KEY(RoleId, GiftId), 0).

%% 触发达成礼包，状态为已经领取
trigger_finish(RoleId, GiftId) ->
    Now = utime:unixtime(),
    Sql = io_lib:format(?SQL_GIFT_LIST_INSERT, [RoleId, GiftId, Now, Now, 1, 1]),
    db:execute(Sql),
    mod_daily_dict:set_special_info(?GIFT_CACHE_KEY(RoleId, GiftId), 1).


%% 获取礼包内容
get_gift_info(Ps, TypeId) ->
    #player_status{sid = Sid, figure = #figure{career = TCareer}} = Ps,
    case data_goods_type:get(TypeId) of
        #ets_goods_type{type=?GOODS_TYPE_GIFT,subtype = 2} -> %% 自选礼包
            {OptionalNum, OptionalGiftList} = case {data_optional_gift:get_by_id(TypeId, TCareer), data_optional_gift:get_by_id(TypeId, 0)} of
                {#optional_gift{optional_num = TOptionalNum, list = List}, _} -> {TOptionalNum, [Goods||{_Id, Goods}<-List]};
                {_, #optional_gift{optional_num = TOptionalNum, list = List}} -> {TOptionalNum, [Goods||{_Id, Goods}<-List]};
                {_, _} -> {0, []}
            end,
            lib_server_send:send_to_sid(Sid, pt_150, 15087, [TypeId, ?GIFTBAG_TYPE_OPTIONAL, OptionalNum, OptionalGiftList, []]);
        #ets_goods_type{type = ?GOODS_TYPE_GIFT} -> %% 普通礼包
            case data_gift:get(TypeId) of
                #ets_gift{filter = Filter} ->
                    [Lv, Sex, Career, Turn] = lib_gift_check:get_filter_items(Filter, Ps, [0, 0, 0, 0]),
                    case data_gift:get_gift_reward(TypeId, Lv, Sex, Career, Turn) of
                        RewardCfg when is_record(RewardCfg, ets_gift_reward) ->
                            do_get_gift_info_core(Ps#player_status.sid, RewardCfg);
                        _ -> %% 容错
                            ConditionList = data_gift:get_condition_by_id(TypeId),
                            case do_get_gift_info(ConditionList, Lv, Sex, Career, Turn, []) of
                                [{Slv, NeedSex, NeedCareer, NeedTurn}|_] ->
                                    RewardCfg = data_gift:get_gift_reward(TypeId, Slv, NeedSex, NeedCareer, NeedTurn),
                                    do_get_gift_info_core(Ps#player_status.sid, RewardCfg);
                                _ -> skip
                            end
                    end;
                _ -> skip
            end;
        _ ->
            skip
    end.

do_get_gift_info([], _Lv, _Sex, _Career, _Turn, Result) -> lists:reverse(Result);
do_get_gift_info([{SLv, _ELv, NeedSex, NeedCareer, NeedTurn}|ConditionList], Lv, Sex, Career, Turn, Result) ->
    if
        (NeedSex == 0 orelse NeedSex == Sex) andalso Turn >= NeedTurn ->
            do_get_gift_info(ConditionList, Lv, Sex, Career, Turn, [{SLv, NeedSex, NeedCareer, NeedTurn}|Result]);
        true ->
            do_get_gift_info(ConditionList, Lv, Sex, Career, Turn, Result)
    end;
do_get_gift_info([_|ConditionList], Lv, Sex, Career, Turn, Result) ->
    do_get_gift_info(ConditionList, Lv, Sex, Career, Turn, Result).

do_get_gift_info_core(Sid, RewardCfg) when is_record(RewardCfg, ets_gift_reward) ->
    #ets_gift_reward{goods_id=TypeId, rand = RandTime, rand_gifts = RandGifts, fixed_gifts = FixedGifts} = RewardCfg,
    case RandTime of
        0 -> %% 纯固定礼包
            RandomRewardList = [],
            GiftBagType = ?GIFTBAG_TYPE_FIX;
        _ ->
            GiftBagType = ?IF(FixedGifts == [], ?GIFTBAG_TYPE_RANDOM, ?GIFTBAG_TYPE_FIX_RANDOM), %% 固定奖励为空则为纯随机礼包
            RandomRewardList = [Goods||{Goods, _Weight}<-RandGifts]
    end,
    lib_server_send:send_to_sid(Sid, pt_150, 15087, [TypeId, GiftBagType, RandTime, RandomRewardList, FixedGifts]).
