%% ---------------------------------------------------------
%% Author:  xyj
%% Email:   156702030@qq.com
%% Created: 2012-1-3
%% Description: 物品他用类，物品进程内调用
%% --------------------------------------------------------
-module(lib_goods_use).
-compile(export_all).
-include("common.hrl").
-include("def_goods.hrl").
-include("sql_goods.hrl").
-include("goods.hrl").
-include("server.hrl").
-include("buff.hrl").
-include("scene.hrl").
-include("predefine.hrl").
-include("figure.hrl").
-include("errcode.hrl").
-include("rec_recharge.hrl").
-include("def_recharge.hrl").
-include("arena.hrl").
-include("vip.hrl").
-include("def_module.hrl").

%%----------------------------------------------------------------
%% @dco 使用物品
%% -spec use_goods(PlayerStatus, Status, GoodsInfo, GoodsNum) ->
%%          {ok, NewPlayerStatus, NewStatus, NewNum} | {fail, ERRCODE}
%% when
%%          PlayerStatus|NewPlayerStatus :: #player_status{} 玩家记录
%%          Status|NewStatus             :: #goods_status{}  物品进程状态
%%          GoodsInfo                    :: #goods{}         物品信息
%%          GoodsNum                     :: integer()        数量
%% @end
%%---------------------------------------------------------------------------
%% @doc 注意！！！
%%  由各自功能决定什么时候扣除道具，使用道具这里不再统一扣除道具
%%
use_goods(PlayerStatus, GoodsStatus, GoodsInfo, GoodsNum) ->
    case use_goods(GoodsInfo#goods.type, PlayerStatus, GoodsStatus, GoodsInfo, GoodsNum) of
        {ok, NewPlayerStatus, TrueNum} when is_integer(TrueNum) ->
            {ok, NewPlayerStatus, TrueNum};
        {ok, NewPlayerStatus, _NewGoodsStatus} ->
            {ok, NewPlayerStatus, GoodsNum};
        {use_fashion_color_goods, NewPlayerStatus, TrueNum, Errcode} ->
            {use_fashion_color_goods, NewPlayerStatus, TrueNum, Errcode};
        {use_designtion_good, NewPlayerStatus, Coin, UsedNum} -> %% 使用称号获得铜币
            {use_designtion_good, NewPlayerStatus, UsedNum, Coin};
        {use_child_upgrade_material, NewPlayerStatus, UsedNum} ->
            {use_child_upgrade_material, NewPlayerStatus, UsedNum};
        {use_sp_vip_goods, NewPlayerStatus, UsedNum} ->
            {use_sp_vip_goods, NewPlayerStatus, UsedNum};
        {fail, Errcode} ->
            {fail, Errcode};
        _Error ->
            _Error
    end.
%% 特殊类
use_goods(?GOODS_TYPE_STUFF, PlayerStatus, Status, GoodsInfo, GoodsNum) ->
    VipGoods = lib_vip_api:get_vip_goods(),
    case lists:member(GoodsInfo#goods.goods_id, VipGoods) of
        true ->
            lib_vip_util:use_vip_goods(PlayerStatus, GoodsInfo, GoodsNum);
        _ ->
            use_stuff_goods(PlayerStatus, GoodsInfo, GoodsNum, Status)
    end;
use_goods(?GOODS_TYPE_FASHION, PlayerStatus, Status, GoodsInfo, GoodsNum) ->
    use_goods_fashion(PlayerStatus, GoodsInfo, GoodsNum, Status);
%% 称号类
use_goods(?GOODS_TYPE_DSGT, PlayerStatus, Status, GoodsInfo, GoodsNum) ->
    use_goods_dsgt(PlayerStatus, GoodsInfo, GoodsNum, Status);
use_goods(?GOODS_TYPE_BABY, PlayerStatus, Status, GoodsInfo, GoodsNum) ->
    use_child_material(PlayerStatus, GoodsInfo, GoodsNum, Status);
use_goods(_, _PlayerStatus, _Status, _GoodsInfo, _GoodsNum) ->
    {fail, ?ERRCODE(err150_type_err)}.

%%-----------------------------------------------------------------------
%% @doc 使用材料类道具
%% -spce use_stuff_goods(PlayStatus, GoodsInfo, GoodsNum, Status) ->
%%      {ok, NewPlayerStatus} | {fail, ErrCode}|{ok, NewPlayerStatus, NewStatus} | nothing
%% @end
%%-------------------------------------------------------------------------
use_stuff_goods(PlayerStatus, GoodsInfo, GoodsNum, _GoodsStatus) ->
    #goods{goods_id = GoodsTypeId, subtype = SubType, bind = _Bind} = GoodsInfo,
    case SubType of
        %% 直接增加虚拟货币，暂无
%%        ?GOLD -> %% 源晶
%%            Gold = data_goods:get_effect_val(GoodsTypeId, gold),
%%            NewGold = Gold * GoodsNum,
%%            NewPs = goods_add:add_money(PlayerStatus, NewGold, ?TYPE_GOLD, goods_use, ""),
%%            {ok, NewPs};
%%        ?BGOLD -> %% 碎晶
%%            BGold = data_goods:get_effect_val(GoodsTypeId, bgold),
%%            NewBGold = BGold * GoodsNum,
%%            NewPs = goods_add:add_money(PlayerStatus, NewBGold, ?TYPE_BGOLD, goods_use, ""),
%%            {ok, NewPs};
%%        ?COIN -> %% 交易券
%%            BGold = data_goods:get_effect_val(GoodsTypeId, coin),
%%            NewBGold = BGold * GoodsNum,
%%            NewPs = goods_add:add_money(PlayerStatus, NewBGold, ?TYPE_COIN, goods_use, ""),
%%            {ok, NewPs};
        %% 充值卡
        ?GOODS_STUFF_SUBTYPE_CHARGE_CARD ->
            ProductId = data_goods:get_effect_val(GoodsInfo#goods.goods_id, charge_card),
            Product = lib_recharge_check:get_product(ProductId),
            #base_recharge_product{product_type = ProductType} = Product,
            Check = lib_recharge_check:check_product(ProductId),
            case {ProductType, Check} of
                %% 普通充值(含充值返利)商品由本身内部控制
                {?PRODUCT_TYPE_NORMAL, _} ->
                    lib_goods_api:cost_object_list(PlayerStatus, [{?TYPE_GOODS, GoodsInfo#goods.goods_id, GoodsNum}], goods_use, ""),
                    NewPs = lib_recharge:pay_by_goods(PlayerStatus, Product, GoodsInfo#goods.goods_id),
                    {ok, NewPs, 1};
                {_, {false, Res}} ->
                    {fail, Res};
                {_, {true, _Product2}} ->
                    lib_goods_api:cost_object_list(PlayerStatus, [{?TYPE_GOODS, GoodsInfo#goods.goods_id, GoodsNum}], goods_use, ""),
                    NewPs = lib_recharge:pay_by_goods(PlayerStatus, Product, GoodsInfo#goods.goods_id),
                    {ok, NewPs, 1}
            end;
        ?GOODS_STUFF_SUBTYPE_CONSUME when GoodsTypeId =:= ?GOODS_ID_EVIL_REDUCE -> %% 免罪券
            lib_player_record:use_red_name_goods(PlayerStatus, GoodsTypeId, GoodsNum);
        ?GOODS_STUFF_SUBTYPE_EXP_PILL -> %% 经验丹
            Ret = use_stuff_goods_exp(PlayerStatus, GoodsTypeId, GoodsNum),
            case Ret of
                {ok, NewPs} -> {ok, NewPs, GoodsNum};
                {false, Errcode} ->
                    {fail, Errcode}
            end;
        ?GOODS_STUFF_SUBTYPE_UP_PILL -> %% 等级直升丹
            Ret = use_stuff_goods_exp(PlayerStatus, GoodsTypeId, GoodsNum),
            case Ret of
                {ok, NewPs} -> {ok, NewPs, GoodsNum};
                {false, Errcode} ->
                    {fail, Errcode}
            end;
        ?GOODS_STUFF_SUBTYPE_EXP_RATIO -> %% 经验药水
            case lib_goods_buff:use_buff_goods(PlayerStatus, GoodsInfo, GoodsNum) of
                {ok, Player} ->
                    Player1 = lib_player:update_exp_add_ratio(Player),
                    {ok, Player1, GoodsNum};
                Res -> Res
            end;
        % ?GOODS_GAIN_STYPE_POWER_LIVE -> %% 增加活力道具
        %     AddLive = case data_goods:get_effect_val(GoodsTypeId, power_live) of
        %                   [] -> 0;
        %                   Val -> Val
        %               end,
        %     case lib_activitycalen_api:add_power_live(PlayerStatus, AddLive * GoodsNum, ?MOD_GOODS, 0) of
        %         ok ->
        %             lib_fishing:send_fishing_info(PlayerStatus),
        %             {ok, PlayerStatus, GoodsNum};
        %         {false, Errcode} -> {fail, Errcode}
        %     end;
        ?GOODS_STUFF_SUBTYPE_FOSTER_UP -> %% vip进阶系统直升丹
            lib_role_foster:use_stuff_up_fosters(PlayerStatus, GoodsInfo, GoodsNum);
        ?GOODS_STUFF_SUBTYPE_CONTRACT_SCORE when GoodsTypeId == ?CONTRACT_GOODS_1 ->
            custom_act_contract:use_goods(PlayerStatus, GoodsInfo, GoodsNum);
        ?GOODS_STUFF_SUBTYPE_CONTRACT_SCORE when GoodsTypeId == ?PHANTOM_GOODS_1 -> %% 幻魔宝典增加积分
            custom_act_phantom:use_goods(PlayerStatus, GoodsInfo, GoodsNum);
        ?GOODS_STUFF_SUBTYPE_BOSS_TIMES when GoodsTypeId == ?BOSS_TIMES_CARD_2 ->
            lib_dungeon:use_goods_add_daily_times(PlayerStatus, GoodsNum);
        ?GOODS_STUFF_SUBTYPE_BOSS_TIMES ->
            local_boss_api:use_goods_cut_tired(PlayerStatus, GoodsTypeId, GoodsNum);
        ?GOODS_STUFF_SUBTYPE_EXP_DROP_BUFF ->
            exp_dun_drop_api:use_goods(PlayerStatus, GoodsInfo, GoodsNum);
        _ ->
            {fail, ?ERRCODE(err150_type_err)}
    end.
use_stuff_goods_exp(PlayerStatus, GoodsTypeId, GoodsNum) ->
    #player_status{figure = #figure{lv = Lv}} = PlayerStatus,
    {UpLv, Exp} =
        case data_goods_effect:get_goods_dynamic_exp(GoodsTypeId, Lv) of
            [0, 0] -> {0, data_goods:get_effect_val(GoodsTypeId, exp)};
            [AddExp, AddLv] -> {AddLv, AddExp};
            _ -> {0, 0}
        end,
    ExtraExp = Exp * GoodsNum,
    MaxLv = data_exp:get_max_lv(),
    Fun = fun(_I, {NowLv, NowExp}) ->
        TmpExp = data_exp:get(NowLv),
        {min(NowLv + 1, MaxLv), TmpExp + NowExp}
          end,
    {_, UpExp} = lists:foldl(Fun, {Lv, 0}, lists:seq(1, UpLv * GoodsNum)),
    NewExp = ExtraExp + UpExp,
    if Exp == 0 ->
            case data_goods_effect:get_goods_lv(GoodsTypeId) of
                CfgLvs = [_|_] ->
                    MinLv = calc_goods_lv(Lv, CfgLvs),
                    {false, {?ERRCODE(err150_goods_lv_limit), [MinLv]}};
                _ ->
                    {false, ?ERRCODE(err150_lv_goods)}
            end;
        true ->
            lib_goods_api:cost_object_list(PlayerStatus, [{0, GoodsTypeId, GoodsNum}], goods_use, ""),
            NewPs = lib_player:add_exp(PlayerStatus, NewExp, exp_goods),
            {ok, NewPs}
    end.

calc_goods_lv(Lv, CfgLvs) ->
    MinLvs = [MinLv || {MinLv, _MaxLv} <- CfgLvs],
    calc_goods_lv_1(Lv, MinLvs).

calc_goods_lv_1(_Lv, []) -> 0;
calc_goods_lv_1(Lv, [MinLv|Rest]) ->
    if Lv >= MinLv ->
            calc_goods_lv_1(Lv, Rest);
        true ->
            MinLv
    end.

use_goods_fashion(PlayerStatus, GoodsInfo, GoodsNum, _Status) ->
    case GoodsInfo#goods.subtype of
        1 -> %% 时装染色类道具
            lib_fashion:use_fashion_color_goods(PlayerStatus, GoodsInfo, GoodsNum);
        _ ->
            {fail, ?FAIL}
    end.

use_goods_dsgt(PlayerStatus, GoodsInfo, GoodsNum, _Status) ->
   case GoodsInfo#goods.subtype of
        1 ->
           lib_designation:use_dsgt_goods(PlayerStatus, GoodsInfo, GoodsNum);
       _ ->
           {fail, ?FAIL}
   end.

use_child_material(PlayerStatus, GoodsInfo, GoodsNum, _Status) ->
    case GoodsInfo#goods.subtype of
        ?GOODS_CHILD_UPGRADE_MATERIAL ->
            lib_child:upgrade_link_heart_with_material(PlayerStatus, GoodsInfo#goods.goods_id, GoodsNum);
        _ ->
            {fail, ?FAIL}
    end.