%% -------------------------------
%% desc	 :放置经验检测
%% module:exp_dun_drop_check.erl
%% author:hh
%% time	 :20/02/11
%% -------------------------------

-module(exp_dun_drop_check).

-include("errcode.hrl").
-include("server.hrl").
-include("figure.hrl").
-include("exp_dun_drop.hrl").
-include("def_module.hrl").
-include("def_goods.hrl").
-include("common.hrl").

-export ([
	role_drop_check/2,
	fast_drop_reward_check/2
	]).

role_drop_check(DropRole, _Time) ->
	#drop_role{
		wave_point = WavePoint, is_rewarding = IsRewarding,
		start_time = StartTime, calc_time = CalcTime, 
		extra_data = ExtraData
	} = DropRole,
	CheckList = [
		{drop_open_check, WavePoint},
		{is_rewarding_check, IsRewarding},
		{drop_time_check, StartTime, CalcTime, ExtraData}
	],
	case do_check(CheckList) of
		true ->
			true;
		{false, _Errcode} ->
			false
	end.

fast_drop_reward_check(Player, RewardTimes) ->
	#player_status{
		id = RoleId, dungeon_record = _Record, exp_dun_drop = ExpDunDrop, figure = #figure{lv = Lv}, vip_status = VipStatus
	} = Player,
	CheckList = [
		{reward_count_check, Player},
		{reward_times_check, RewardTimes, VipStatus},
		{fast_drop_time_check, ExpDunDrop, Lv}
		% {exp_dun_wave_check, Record}
	],
	case do_check(CheckList) of
		true ->
			Res = if RewardTimes == 3 -> %% 类型3代表双倍 ->
					CanUseCount = custom_unite_buff:check_times(Player, free_fast_exp),
					ConfigCostMoney = data_exp_dun_drop:get_kv(5),
					if CanUseCount > 0 ->
							{true, Player, [], CanUseCount};
						true ->
						 	case lib_goods_api:cost_money(Player, ?TYPE_GOLD, ConfigCostMoney, fast_exp_drop_cost, "") of
						 		{1, NewPlayer} -> {true, NewPlayer, [{?TYPE_GOLD, 0, ConfigCostMoney}], CanUseCount};
						 		_ 			   -> {false, ?ERRCODE(err150_no_money)}
						 	end
					end;
				true ->
					{true, Player, [], 0}
			end,
			case Res of
				{true, NewPlayer1, Cost, RestCount} ->
					#base_fast_onhook_reward{base_exp = BaseExp} = data_exp_dun_drop:get_lv_onhook_exp(Lv),
					RealRewardsTimes = get_real_reward_times(RewardTimes),
					DropedCount = lib_daily:get_count(RoleId, ?MOD_DUNGEON, ?MOD_EXP_DUN_FAST_DROP),
					if RestCount > 0 ->
							custom_unite_buff:cost_times(NewPlayer1, free_fast_exp);
						true ->
							skip
					end,
					{true, NewPlayer1, BaseExp, RealRewardsTimes, DropedCount, RestCount, Cost};
				{false, Errcode} ->
					{false, Errcode}
			end;
		{false, Errcode} ->
			{false, Errcode}
	end.

%% 返回奖励倍数
get_real_reward_times(Times) ->
	RewardTimeList = data_exp_dun_drop:get_kv(9),
	SortTimeList   = lists:keysort(1, RewardTimeList),
	TimeLen 	   = length(SortTimeList),
	if Times =/= 0 andalso Times =< TimeLen ->
			{RewardTimes, _} = lists:nth(Times, SortTimeList),
			RewardTimes;
		true ->
			1
	end.
% get_real_reward_times(1) -> 1;
% get_real_reward_times(2) -> 1.25;
% get_real_reward_times(3) -> 1.5;
% get_real_reward_times(_) -> 1.

do_check([]) -> true;
do_check([{drop_open_check, WavePoint}|Rest]) ->
	%% 只要通关了经验本第一波,则默认开启
	%% 过时之后,会保留最近的一次波数通关记录
	%% 其余删除,以免长期保存大量多余数据
    case WavePoint of
        [_|_] -> do_check(Rest);
        _     -> {false, ?FAIL}
    end;
do_check([{is_rewarding_check, IsRewarding}|Rest]) ->
	if IsRewarding =/= ?EXP_DROP_REWARDING ->
			do_check(Rest);
		true ->
			{false, ?FAIL}
	end;
do_check([{drop_time_check, StartTime, CalcTime, ExtraData}|Rest]) ->
	ResourceLimit = lib_exp_dun_drop:get_exp_drop_time_limit(ExtraData),
	%% 判断掉落时长是否已超过配置上限
    TimeLimit = ResourceLimit*3600,
    DefaultData   = lib_exp_dun_drop:get_default_calc_time(CalcTime, StartTime),
    TimeLast      = lib_exp_dun_drop:get_calc_time_last(ExtraData, DefaultData),
    if TimeLast < TimeLimit ->
            do_check(Rest);
        true ->
            {false, ?ERRCODE(err610_drop_time_limit)}
    end;
do_check([{reward_count_check, Player}|Rest]) ->
	TotalCount = fast_exp_drop:get_fast_drop_max_count(Player),
 	RewardCount = lib_daily:get_count(Player#player_status.id, ?MOD_DUNGEON, ?MOD_EXP_DUN_FAST_DROP),
 	if RewardCount < TotalCount ->
 			do_check(Rest);
 		true ->
 			{false, ?ERRCODE(err110_times_not_enough)}
 	end;
do_check([{reward_times_check, RewardTimes, VipStatus}|Rest]) ->
	if RewardTimes =/= 1 andalso RewardTimes =/= 2 andalso RewardTimes =/= 3 ->
			{false, ?ERRCODE(err153_goods_not_equal)};
		true ->
			if RewardTimes == 2 ->
					case lib_sup_vip:is_sup_vip(VipStatus) of
						true ->
							do_check(Rest);
						_ ->
							{false, ?ERRCODE(err451_no_sup_vip)}
					end;
				true ->
					do_check(Rest)
			end
	end;
do_check([{fast_drop_time_check, ExpDunDrop, Lv}|Rest]) ->
	case ExpDunDrop of
		#role_exp_dun_drop{fast_drop_time = StartTime} ->
			case data_exp_dun_drop:get_lv_onhook_exp(Lv) of
				#base_fast_onhook_reward{time = Time} ->
					Now = utime:unixtime(),
					if StartTime == 0 ->
							{false, ?ERRCODE(err150_time_not_start)};
						true ->
							GetTime = StartTime + Time,
							if Now >= GetTime ->
									do_check(Rest);
								true ->
									{false, ?ERRCODE(err150_time_not_start)}
							end
					end;
				_ ->
					{false, ?ERRCODE(err153_goods_not_equal)}
			end;
		_ ->
			{false, ?ERRCODE(err153_goods_not_equal)}
	end;
% do_check([{exp_dun_wave_check, Record}|Rest]) ->
% 	case fast_exp_drop:get_exp_dun_max_wave(Record) of
% 		Wave when Wave =/= 0 ->
% 			do_check(Rest);
% 		_ ->
% 			{false, ?ERRCODE(err153_goods_not_equal)}
% 	end;
do_check([_|_Rest]) ->
	{false, ?FAIL}.