%%%--------------------------------------
%%% @Module  : lib_vip_api
%%% @Author  : yxf
%%% @Created : 2017-11-13
%%% @Description:  vip
%%%--------------------------------------
-module(lib_vip_api).
-include("server.hrl").
-include("figure.hrl").
-include("errcode.hrl").
-include("vip.hrl").
-include("predefine.hrl").
-include("common.hrl").
-include("def_goods.hrl").
-include("def_event.hrl").
-include("def_fun.hrl").
-include("rec_event.hrl").
-include("def_module.hrl").
-include("def_daily.hrl").
-include("def_vip.hrl").
-include("skill.hrl").

-export ([
    handle_event/2,                 %% 事件派发监听
    get_vip_lv/1,                   %% 获取当前VIP真实等级
    get_valid_vip_lv/1,             %% 获取当前vip类型等级
    get_vip_privilege/3,            %% 获取vip特权
    get_vip_privilege/4,            %% 获取vip特权-多一个特权类型参数
    check_daily_cur_limit/4,        %% 判断每日货币上限
    get_vip_goods/0,
    check_is_vip_previlege_skill/1,
    get_vip_pre_skill_by_career/1,
    % check_gold_gift_vip_limit/2,
    check_mail_vip_gold_limit/3,
    add_vip_exp/2                  %% 增加vip经验
    ]).

%% 玩家消耗钻石完成的时候执行
handle_event(PS, #event_callback{type_id = ?EVENT_MONEY_CONSUME, data = _Data})  ->
    {ok, PS};
%% vip 登陆延后事件
handle_event(PS, #event_callback{type_id = ?EVENT_LOGIN_CAST}) ->
    %% 设置定时器
    TmpPS = lib_vip:set_time_out_caller(PS),
    NewPS = lib_player:update_exp_dun_drop_ratio(TmpPS),
    {ok, NewPS};
%% 充值触发vip增加经验
handle_event(PS, #event_callback{type_id = ?EVENT_RECHARGE, data = #callback_recharge_data{gold = Gold, is_charge_card = IsChargeCard}}) ->
    NewPS = lib_vip:calc_vip_status(PS, Gold, IsChargeCard),
    {ok, NewPS};
handle_event(PS, _) ->
    {ok, PS}.

%% vip等级,有可能处于体验阶段
-spec get_valid_vip_lv(Player) -> {VipType, RealLv, VipLv} when
Player  :: #player_status{},
VipType :: integer(),     %% vip类型 1非体验vip或正常vip|0体验式vip
RealLv  :: integer(),     %% 真实vip等级
VipLv   :: integer().     %% 体验vip等级
get_valid_vip_lv(Player) ->
    #player_status{vip_status = #vip_status{type = VipType, lv = RealLv, trial_lv = Lv}} = Player,
    {VipType, RealLv, Lv}.

%% 真实vip等级
-spec get_vip_lv(#player_status{}) -> integer().
get_vip_lv(Player) ->
    Player#player_status.vip_status#vip_status.lv.

%% 获取vip特权
-spec get_vip_privilege(Player, ClassId, SubclassId) -> integer() when
Player      :: #player_status{},
ClassId     :: integer(),   %% 功能id
SubclassId  :: integer().   %% 功能子id
get_vip_privilege(Player, ClassId, SubclassId) ->
    get_vip_privilege(Player, ClassId, SubclassId, 1).

get_vip_privilege(Player, ClassId, SubclassId, PrivilegeId) ->
    {VipType, RealLv, VipLv} = get_valid_vip_lv(Player),
    lib_vip:get_vip_privilege(RealLv, VipType, VipLv, ClassId, SubclassId, PrivilegeId).


%% 检测每日限定货币类型产出限制
-spec check_daily_cur_limit(RoleId, VipStatus, CurrencyType, Add) -> ReturnType when
    RoleId :: integer(),            %% 人物id
    VipStatus :: integer(),         %% vip数据
    CurrencyType :: integer(),      %% 货币类型 ？TYPE_GOLD| ？TYPE_BGOLD
    Add :: integer(),               %% 产出
    ReturnType :: boolean().        %% true 可继续产出|false 已达上限,不可继续产出
check_daily_cur_limit(RoleId, VipStatus, CurrencyType, Add) ->
    case data_vip:get_vip(VipStatus) of
        #base_vip_cfg{daily_gold_limit = GoldLimit, daily_bgold_limit = BGoldLimit} ->
            Limit = if CurrencyType == ?TYPE_GOLD -> GoldLimit;
                true -> BGoldLimit
            end,
            if Limit == 0 ->
                    true;
                true -> %% Limit =/= 0
                    TodayNum = lib_daily:get_count(RoleId, ?MOD_VIP, ?VIP_DAILY_CURRENCY_LIMIT, CurrencyType),
                    NewTodayNum = TodayNum + Add,
                    % ?ERR("~p ~p ~p", [TodayNum, NewTodayNum, Limit]),
                    if (TodayNum < Limit andalso NewTodayNum >= Limit) orelse NewTodayNum =< Limit ->
                            lib_daily:set_count(RoleId, ?MOD_VIP, ?VIP_DAILY_CURRENCY_LIMIT, CurrencyType, NewTodayNum),
                            true;
                        true -> %% TodayNum >= Limit
                            false
                    end
            end;
        _ ->
            if VipStatus == 0 ->
                    Vip0Limit = if CurrencyType == ?TYPE_GOLD ->
                            data_vip:get_cfg(5);
                        true ->
                            data_vip:get_cfg(4)
                    end,
                    TodayNum = lib_daily:get_count(RoleId, ?MOD_VIP, ?VIP_DAILY_CURRENCY_LIMIT, CurrencyType),
                    NewTodayNum = TodayNum + Add,
                    if (TodayNum < Vip0Limit andalso NewTodayNum >= Vip0Limit) orelse NewTodayNum =< Vip0Limit ->
                            lib_daily:set_count(RoleId, ?MOD_VIP, ?VIP_DAILY_CURRENCY_LIMIT, CurrencyType, NewTodayNum),
                            true;
                        true -> %% TodayNum >= Vip0Limit
                            false
                    end;
                true ->
                    true
            end
    end.

-spec check_mail_vip_gold_limit(RoleId, Vip, {AddGold, AddBgold}) -> ReturnType when
    RoleId :: integer(),
    Vip :: integer(),
    AddGold :: integer(),
    AddBgold :: integer(),
    ReturnType :: true | {false, integer()}. %% true 不限制| false 限制
check_mail_vip_gold_limit(RoleId, Vip, {AddGold, AddBgold}) ->
    GoldLimit  = check_daily_cur_limit(RoleId, Vip, ?TYPE_GOLD, AddGold),
    BGoldLimit = check_daily_cur_limit(RoleId, Vip, ?TYPE_BGOLD, AddBgold),
    if (not GoldLimit) andalso (not BGoldLimit) ->
            {false, ?ERRCODE(err150_gold_daily_limit)};
        true ->
            true
    end.

%% 奖励产出,增加vip经验
-spec add_vip_exp(Player, Val) -> NewPlayer when
    Player :: #player_status{},
    Val :: integer(),
    NewPlayer :: #player_status{}.
add_vip_exp(Player, Val) ->
    NewPlayer = lib_vip:calc_vip_status(Player, Val),
    NewPlayer.


get_vip_goods() ->
    [G|| {G, _} <- data_vip:get_cfg(1)] ++ [G1 || {G1, _, _} <- data_vip:get_cfg(2)].


% check_skill_previlege(Player, SkillId) ->
%     VipSkillL = data_vip:get_cfg(3),
%     case lists:member(SkillId, VipSkillL) of
%         true ->
%             case get_vip_privilege(Player, ?CAREER_SPECIL_SKILL, 1) of
%                 Val when is_integer(Val) andalso Val =/= 0 ->
%                     true;
%                 _ ->
%                     {false, ?ERRCODE(err450_vip_skill_limit)}
%             end;
%         _ ->
%             true
%     end.

check_is_vip_previlege_skill(SkillId) ->
    VipSkillL = data_vip:get_cfg(3),
    case lists:member(SkillId, VipSkillL) of
        true ->
            true;
        false ->
            false
    end.

get_vip_pre_skill_by_career(Career) ->
    VipSkillL = data_vip:get_cfg(3),
    case lists:filter(fun(SkillId) -> 
        case data_skill:get(SkillId, 1) of
            #skill{career = Career} -> true;
            _   -> false
        end
    end, VipSkillL) of
        [VipSkillId|_] -> VipSkillId;
        _   -> VipSkillId = 0
    end,
    VipSkillId.