%%-----------------------------------------------------------------------------
%% @Module  :       lib_fashion_check
%% @Author  :       WJQ
%% @Created :       2018-12-18
%% @Description:    时装检测
%%-----------------------------------------------------------------------------
-module(lib_fashion_check).

-include("common.hrl").
-include("fashion.hrl").
-include("server.hrl").
-include("errcode.hrl").
-include("figure.hrl").
-include("def_goods.hrl").
-include("goods.hrl").

-export([
	color_operate_check/4
	,decompose_check/2
	,equip_fashion_color_check/4
	,unequip_fashion_color_check/3
	,active_fashion_use_goods_check/6
]).


%% 分解检测
decompose_check(#player_status{role_fashion = RoleFashion} = Player, GoodIdList) ->
	#role_fashion{all_fashions = AllFashions} = RoleFashion,
	case lists:keyfind(?GOODS_TYPE_FASHION, 1, GoodIdList) of
		{_, _RewardIdList} ->
			%% return - {true, [{id, goods_type_id, num}]}
			GoodsStatus = lib_goods_do:get_goods_status(),
			GoodsDict   = GoodsStatus#goods_status.dict,
			GoodList = lib_goods_util:get_goods_list_by_type(
				Player#player_status.id, ?GOODS_LOC_BAG, ?GOODS_TYPE_FASHION, GoodsDict),
			F = fun(#goods{id = GoodsId, goods_id = GoodsTypeId, num = Num}, TList) ->
						[{GoodsId, GoodsTypeId, Num}|TList]
				end,
			HasGoodsList = lists:foldl(F, [], GoodList),
			ActiveFashions = calc_all_active_fashion(AllFashions),
			DecomposeList = [{TGoodsId, TGoodsTypeId, TNum}||{TGoodsId, TGoodsTypeId, TNum}<-HasGoodsList,
				lists:member(TGoodsTypeId, ActiveFashions)],
			case DecomposeList =/= [] of
				true ->
					{true, DecomposeList};
				_ ->
					{false, []}
			end;
		_ ->
			{false, []}
	end.

%% 永久激活的时装才计算在内
calc_all_active_fashion(AllFashions) ->
	Filter = fun(#fashion_pos{fashion_list = FashionList}, TFilterList) ->
		F = fun(#fashion_info{fashion_id = FashionId, color_list = ColorList}, TList) ->
			F1 = fun({ColorId, _, Time}, TList1) when Time =< 0 ->
				case data_fashion:get_fashion_con(FashionId, ColorId, 0) of
					#base_fashion_star_up{cost_goods = [{_, GoodsTypeId, _}|_]} ->
						[GoodsTypeId|TList1];
					_ -> TList1
				end;
				(_, TList1) -> TList1
			end,
			lists:foldl(F1, TList, ColorList)
		end,
		lists:foldl(F, TFilterList, FashionList)
	end,
	FilterList = lists:foldl(Filter, [], AllFashions),
	FilterList.

%% 正常激活升星操作
color_operate_check(Player, PosId, FashionId, ColorId) ->
	#player_status{role_fashion = RoleFashion} = Player,
	#role_fashion{all_fashions = FashionPosList} = RoleFashion,
	OperateType = check_operate_type(PosId, FashionId, ColorId, FashionPosList),
	% ?ERR("~p", [OperateType]),
	case get_star_cost(OperateType, FashionId, ColorId) of
		CostLsit = [_|_] ->
			CheckL = [
				{check_cost, CostLsit, Player}
			],
			case check_list(CheckL) of
				true ->
		            case goods_del:cost_object_list(Player, CostLsit, fashion_star, "") of
		                {true, NewPlayer} ->
		                    {true, NewPlayer, OperateType, CostLsit};
		                {false, ErrorCode, _NewPS} ->
		                    {false, ErrorCode}
		            end;
					% {true, OperateType};
				{false, Errcode} ->
					{false, Errcode}
			end;
		[] ->
			{false, ?ERRCODE(missing_config)};
		{false, Errcode} ->
			{false, Errcode}
	end.

check_operate_type(PosId, FashionId, ColorId, FashionPosList) ->
	case lists:keyfind(PosId, #fashion_pos.pos_id, FashionPosList) of
		#fashion_pos{fashion_list = FashionList} ->
			case lists:keyfind(FashionId, #fashion_info.fashion_id, FashionList) of
				#fashion_info{color_list = ColorList} ->
					case lists:keyfind(ColorId, 1, ColorList) of
						{_, Star, ExpireTime} when ExpireTime == 0 ->
						 	MaxStar = data_fashion:get_color_max_star(FashionId, ColorId),
						 	if Star >= MaxStar ->
						 			{false, ?ERRCODE(err413_fashion_max_star)};
						 		true ->
						 			{?COLOR_STAR_UP, Star}
						 	end;
						{_, _Star, _ExpireTime} -> %% 限时激活永久
							?COLOR_SHORT_ACTIVE_EVER;
						_ ->
							?COLOR_ACTIVE
					end;
				_ ->
					?COLOR_ACTIVE
			end;
		_ ->
			?COLOR_ACTIVE
	end.

get_star_cost(OperateType, FashionId, ColorId) ->
	case OperateType of
		?COLOR_ACTIVE ->
			%% 有整件物品的需要先消耗，没有才消耗碎片
			case data_fashion:get_fashion_con(FashionId, ColorId, 0) of
				#base_fashion_star_up{star_cost = Cost,
					cost_goods = CostGoods = [{_, GoodsTypeId, NeedNum}]} ->
					[{_, OwnNum}] = lib_goods_api:get_goods_num(none, [GoodsTypeId]),
					case OwnNum >= NeedNum of
						true -> CostGoods;
						_ -> Cost
					end;
				_  -> {false, ?ERRCODE(missing_config)}
			end;
		?COLOR_SHORT_ACTIVE_EVER ->
			%% 有整件物品的需要先消耗，没有才消耗碎片
			case data_fashion:get_fashion_con(FashionId, ColorId, 0) of
				#base_fashion_star_up{star_cost = Cost,
					cost_goods = CostGoods = [{_, GoodsTypeId, NeedNum}]} ->
					[{_, OwnNum}] = lib_goods_api:get_goods_num(none, [GoodsTypeId]),
					case OwnNum >= NeedNum of
						true -> CostGoods;
						_ -> Cost
					end;
				_  -> {false, ?ERRCODE(missing_config)}
			end;
		{?COLOR_STAR_UP, Star} ->
			case data_fashion:get_fashion_con(FashionId, ColorId, Star+1) of
				#base_fashion_star_up{star_cost = Cost} -> Cost;
				_  -> {false, ?ERRCODE(missing_config)}
			end;
		{false, Errcode} ->
			{false, Errcode};
		_ ->
			{false, ?FAIL}
	end.

%% 穿戴操作
equip_fashion_color_check(Player, PosId, FashionId, ColorId) ->
	#player_status{role_fashion = RoleFashion} = Player,
	#role_fashion{all_fashions = AllFashions} = RoleFashion,
	FashionPos = lists:keyfind(PosId, #fashion_pos.pos_id, AllFashions),
	if
		not is_record(FashionPos, fashion_pos) ->
			{false, ?ERRCODE(err413_fashion_not_pos)};
		true ->
			#fashion_pos{wear_fashion_id = WearFashionId, wear_color_id = WearColorId, fashion_list = FashionList} = FashionPos,
			FashionInfo = lists:keyfind(FashionId, #fashion_info.fashion_id, FashionList),
			if
				not is_record(FashionInfo, fashion_info) ->
					{false, ?ERRCODE(err413_fashion_not_fashion)};
				WearFashionId == FashionId andalso WearColorId == ColorId ->
					{false, ?ERRCODE(err413_fashion_not_same_color)};
				true ->
					#fashion_info{color_list = ColorList} = FashionInfo,
					case lists:keyfind(ColorId, 1, ColorList) of
						{_, _Star, _Time} ->
							true;
						_ ->
							{false, ?ERRCODE(err413_fashion_color_not_active)}
					end
			end
	end.

%% 卸下操作
unequip_fashion_color_check(Player, PosId, FashionId) ->
	#player_status{role_fashion = RoleFashion} = Player,
	#role_fashion{all_fashions = AllFashions} = RoleFashion,
	FashionPos = lists:keyfind(PosId, #fashion_pos.pos_id, AllFashions),
	if
		not is_record(FashionPos, fashion_pos) ->
			{false, ?ERRCODE(err413_fashion_not_pos)};
		true ->
			#fashion_pos{wear_fashion_id = WearFashionId, wear_color_id = WearColorId, fashion_list = FashionList} = FashionPos,
			FashionInfo = lists:keyfind(FashionId, #fashion_info.fashion_id, FashionList),
			if
				not is_record(FashionInfo, fashion_info) ->
					{false, ?ERRCODE(err413_fashion_not_fashion)};
				WearFashionId =/= FashionId orelse WearColorId == 0 ->
					{false, ?ERRCODE(err413_fashion_not_wear)};
				true ->
					true
			end
	end.

%% 使用物品激活限时时装判断
active_fashion_use_goods_check(Player, FashionId, ColorId, GoodsId, ExpireTime, IsOverLay) ->
	#player_status{role_fashion = RoleFashion} = Player,
	FashionColorCfg = data_fashion:get_fashion_con(FashionId, ColorId, 0),
	IsTrialGoods   = lib_fashion:is_trial_fashion_goods(GoodsId),
	IsTrialFashion = lib_fashion:is_trial_fashion(FashionId),
	if
		not is_record(FashionColorCfg, base_fashion_star_up) ->
			{false, ?ERRCODE(missing_config)};
		not IsTrialGoods ->
			{false, ?ERRCODE(err413_not_trial_goods)};
		not IsTrialFashion ->
			{false, ?ERRCODE(err413_not_trial_fashion)};
		ExpireTime == 0 ->
			{false, ?FAIL};
		true ->
			case data_fashion:get_fashion_pos_id(FashionId) of
				[PosId|_] ->
					#role_fashion{all_fashions = AllFashions} = RoleFashion,
					#fashion_pos{fashion_list = FashionList} = lib_fashion:get_fashion_pos(PosId, AllFashions),
					#fashion_info{color_list = ColorList} = lib_fashion:get_fashion_info(PosId, FashionId, FashionList),
					Now = utime:unixtime(),
					case lists:keyfind(ColorId, 1, ColorList) of
						{_, _OldStar, EndTime} when EndTime == 0 ->
							{false, ?ERRCODE(err413_fashion_color_active)};
						{_, _OldStar, EndTime} when EndTime > Now andalso IsOverLay == 0 ->
							{false, ?ERRCODE(err413_fashion_cannot_overlay)};
						_A ->
							{true, PosId}
					end;
				_A ->
					{false, ?FAIL}
			end
	end.


check_list([]) -> true;
check_list([Msg|Rest]) ->
	case do_check_list(Msg) of
		true ->
			check_list(Rest);
		{false, Errcode} ->
			{false, Errcode}
	end.

do_check_list({check_cost, CostLsit, Player}) ->
	case CostLsit of
		{false, Errcode} ->
			{false, Errcode};
		[_|_] ->
			lib_goods_api:check_object_list(Player, CostLsit);
		_ ->
			{false, ?FAIL}
	end;
do_check_list(_Msg) ->
	{false, ?FAIL}.