%%%-------------------------------------------------------------------
%%% @author  tyl
%%% @doc
%%%      社团竞榜 - 团长任务
%%% @end
%%% Created : 2021-06-29
%%%-------------------------------------------------------------------
-module(lib_guild_race_rank_task).

-include("common.hrl").
-include("server.hrl").
-include("errcode.hrl").
-include("goods.hrl").
-include("guild.hrl").
-include("guild_race_rank.hrl").
-include("def_module.hrl").
-include("def_goods.hrl").
-include("def_fun.hrl").
-include("custom_act.hrl").

-export([
	trigger_create_guild_task/2     %% 创建社团任务
	,trigger_invite_role_task/2     %% 邀请玩家任务
	,trigger_power_up_task/2        %% 总战力提升任务
	,trigger_live_up_task/2         %% 总活跃提升任务
	,trigger_guild_boss_task/2      %% 社团幻魔任务

	,async_trigger_task/4           %% 触发任务
	,trigger_guild_task/5

	,get_task_info/1                %% 获取任务进度数据
	,get_race_rank_task_info/3
	,receive_task_reward/2          %% 领取任务奖励
	,receive_race_rank_task_reward/4
	,delete_race_rank_task/2        %% 删除社团所有任务(社团解散时)

	,db_select_race_rank_task/0
	,db_delete_race_rank_task/1
]).

%% 创建社团任务
trigger_create_guild_task(GuildId, Value) ->
	async_trigger_task(GuildId, ?TASK_TYPE_CREATE_GUILD, Value, 2).
%% 邀请玩家任务
trigger_invite_role_task(GuildId, Value) ->
	async_trigger_task(GuildId, ?TASK_TYPE_INVITE_ROLE, Value, 2).
%% 总战力提升任务
trigger_power_up_task(GuildId, Value) ->
	async_trigger_task(GuildId, ?TASK_TYPE_POWER_UP, Value, 2).
%% 总活跃提升任务
trigger_live_up_task(GuildId, Value) ->
	async_trigger_task(GuildId, ?TASK_TYPE_LIVE_UP, Value, 2).
%% 社团幻魔任务
trigger_guild_boss_task(GuildId, Value) ->
	async_trigger_task(GuildId, ?TASK_TYPE_GUILD_BOSS, Value, 1).


async_trigger_task(GuildId, TaskId, Value, Type) ->
	mod_guild_race_rank:apply_cast(?MODULE, trigger_guild_task, [GuildId, TaskId, Value, Type]),
	ok.

%% param: Type 1-累加型 2-替换型
trigger_guild_task(State, GuildId, TaskId, Value, Type) ->
	#guild_race_rank_state{guild_task = GuildTaskMap, guild_rank_list = GuildRankList} = State,
	TaskList = maps:get(GuildId, GuildTaskMap, []),
	OldTask = case lists:keyfind(TaskId, #guild_race_rank_task.task_id, TaskList) of
		          #guild_race_rank_task{} = Task -> Task;
		          _ -> #guild_race_rank_task{task_id = TaskId}
	          end,
	case check_has_finish(OldTask) of
		true -> {ok, State};
		_ ->
			case lists:keyfind(GuildId, #guild_rank.guild_id, GuildRankList) of
				#guild_rank{captain_id = CaptainId} -> ok;
				_ -> CaptainId = 0
			end,
			NewTask = calc_new_task(OldTask, TaskId, Value, Type),
			db_save_race_rank_task(GuildId, TaskId, NewTask#guild_race_rank_task.progress, NewTask#guild_race_rank_task.status),
			NewTaskList = lists:keystore(TaskId, #guild_race_rank_task.task_id, TaskList, NewTask),
			NewGuildTaskMap = maps:put(GuildId, NewTaskList, GuildTaskMap),
			%% 如果任务完成并且团长在线，推送(前端红点)
			case NewTask#guild_race_rank_task.status >= ?TASK_FINISHED of
				true ->
					Pid = misc:get_player_process(CaptainId),
					case is_pid(Pid) andalso misc:is_process_alive(Pid) of
						true ->
							PackList = pack_guild_task(NewTaskList, true, []),
							lib_server_send:send_to_uid(CaptainId, pt_407, 40706, [PackList]),
							ok;
						_ ->
							ignore
					end;
				_ ->
					ignore
			end,
			{ok, State#guild_race_rank_state{guild_task = NewGuildTaskMap}}
	end.

check_has_finish(Task) ->
	case Task#guild_race_rank_task.status >= ?TASK_FINISHED  of
		true -> true;
		_ -> false
	end.

calc_new_task(OldTask, TaskId, Value, Type) ->
	OldProgress = OldTask#guild_race_rank_task.progress,
	CfgProgress =
		case data_guild_race_rank:get_task(TaskId) of
			#base_guild_race_rank_task{condition = [{_, Condition}]} -> Condition;
			_ -> 9999999999
		end,
	case Type of
		%% 累加型
		?TASK_TYPE_CALC ->
			NewProgress = min(OldProgress + Value, CfgProgress),
			NewTask = case NewProgress >= CfgProgress of
				          true ->
					          OldTask#guild_race_rank_task{progress = NewProgress, status = ?TASK_FINISHED};
				          _ ->
					          OldTask#guild_race_rank_task{progress = NewProgress}
			          end;
		%% 替换型
		_ ->
			NewProgress = Value,
			NewTask = case NewProgress >= CfgProgress of
				          true ->
					          OldTask#guild_race_rank_task{progress = min(NewProgress, CfgProgress), status = ?TASK_FINISHED};
				          _ ->
					          %% 下降不需要替换
					          case NewProgress > OldProgress of
								  true -> OldTask#guild_race_rank_task{progress = NewProgress};
								  _ -> OldTask
					          end
			          end
	end,
	NewTask.

%% --------------------------------------------------------------------------
%% @doc 任务数据 @end
%% --------------------------------------------------------------------------
get_task_info(Player) ->
	#player_status{id = RoleId, guild = StatusGuild} = Player,
	#status_guild{id = GuildId} = StatusGuild,
	mod_guild_race_rank:apply_cast1(?MODULE, get_race_rank_task_info, [GuildId, RoleId]),
	ok.

get_race_rank_task_info(State, GuildId, RoleId) ->
	#guild_race_rank_state{guild_task = GuildTaskMap, guild_rank_list = GuildRankList} = State,
	case lists:keyfind(GuildId, #guild_rank.guild_id, GuildRankList) of
		#guild_rank{create_id = CreateId} -> ok;
		_ -> CreateId = 0
	end,
	TaskList = maps:get(GuildId, GuildTaskMap, []),
	IsCreater = RoleId == CreateId,
	PackList = pack_guild_task(TaskList, IsCreater, []),
	lib_server_send:send_to_uid(RoleId, pt_407, 40706, [PackList]),
	ok.

pack_guild_task([], _IsCreater, PackList) ->
	PackList;
pack_guild_task([Task|L], IsCreater, PackList) ->
	case Task of
		#guild_race_rank_task{
			task_id   = TaskId
			,progress = Progress
			,status   = Status
		} ->
			%% 创建社团任务，非创建者(新的团长/成员)显示任务已领取
			case TaskId of
				1 when IsCreater == false ->
					NewPackList = [{TaskId, Progress, 2}|PackList];
				_ ->
					NewPackList = [{TaskId, Progress, Status}|PackList]
			end,
			pack_guild_task(L, IsCreater, NewPackList);
		_ ->
			pack_guild_task(L, IsCreater, PackList)
	end.

%% --------------------------------------------------------------------------
%% @doc 领取奖励 @end
%% --------------------------------------------------------------------------
%% 创建社团任务必须是创建者才可以领取
receive_task_reward(Player, TaskId) ->
	#player_status{id = RoleId, guild = StatusGuild} = Player,
	#status_guild{id = GuildId} = StatusGuild,
	mod_guild_race_rank:apply_cast1(?MODULE, receive_race_rank_task_reward, [RoleId, GuildId, TaskId]),
	ok.

%% p.s.: 创建社团任务，创建者才可以领取；其他任务现任团长可领取
receive_race_rank_task_reward(State, RoleId, GuildId, TaskId) ->
	#guild_race_rank_state{guild_task = GuildTaskMap, guild_rank_list = GuildRankList} = State,
	case lists:keyfind(GuildId, #guild_rank.guild_id, GuildRankList) of
		#guild_rank{captain_id = CaptainId, create_id = CreatId} -> ok;
		_ -> CaptainId = 0, CreatId = 0
	end,
	IsCaptain = RoleId == CaptainId,
	IsCreater = RoleId == CreatId,
	case IsCaptain of
		false ->
			lib_server_send:send_to_uid(RoleId, pt_407, 40707,
				[?ERRCODE(err407_is_not_captain), TaskId, 0, 0]
			),
			NewState = State;
		_ ->
			TaskList = maps:get(GuildId, GuildTaskMap, []),
			case lists:keyfind(TaskId, #guild_race_rank_task.task_id, TaskList) of
				#guild_race_rank_task{status = Status, progress = Progress} = Task ->
					case Status of
						?TASK_NOT_FINISH ->
							lib_server_send:send_to_uid(RoleId, pt_407, 40707,
								[?ERRCODE(err407_not_finish_task), TaskId, 0, 0]
							),
							NewState = State;
						?TASK_HAS_RECEIVED ->
							lib_server_send:send_to_uid(RoleId, pt_407, 40707,
								[?ERRCODE(err407_has_received), TaskId, 0, 0]
							),
							NewState = State;
						_ ->
							%% 创建社团任务必须是创建者才可以领取
							case TaskId of
								?TASK_TYPE_CREATE_GUILD when IsCreater == false ->
									lib_server_send:send_to_uid(RoleId, pt_407, 40707,
										[?ERRCODE(err407_not_finish_task), TaskId, 1, 2]
									),
									NewState = State;
								_ ->
									case data_guild_race_rank:get_task(TaskId) of
										#base_guild_race_rank_task{reward = Reward} ->
											Produce = #produce{type = guild_race_rank_reward, reward = Reward},
											lib_goods_api:send_reward_with_mail(RoleId, Produce),
											NewTask = Task#guild_race_rank_task{status = ?TASK_HAS_RECEIVED},
											db_update_race_rank_task(GuildId, TaskId, ?TASK_HAS_RECEIVED),
											NewTaskList = lists:keystore(TaskId, #guild_race_rank_task.task_id, TaskList, NewTask),
											NewGuildTaskMap = maps:put(GuildId, NewTaskList, GuildTaskMap),
											lib_server_send:send_to_uid(RoleId, pt_407, 40707,
												[?SUCCESS, TaskId, Progress, ?TASK_HAS_RECEIVED]
											),
											NewState = State#guild_race_rank_state{guild_task = NewGuildTaskMap};
										_ ->
											lib_server_send:send_to_uid(RoleId, pt_407, 40707,
												[?ERRCODE(err407_task_cfg_err), TaskId, 0, 0]
											),
											NewState = State
									end
							end
					end;
				_ ->
					lib_server_send:send_to_uid(RoleId, pt_407, 40707,
						[?ERRCODE(err407_not_finish_task), TaskId, 0, 0]
					),
					NewState = State
			end
	end,
	{ok, NewState}.

%% ------------------------------------------------------------------------------
%% 数据库删除操作已经在前面的逻辑执行，这里只处理内存
delete_race_rank_task(State, GuildIdList) ->
	#guild_race_rank_state{guild_task = GuildTaskMap} = State,
	F = fun(GuildId, TGuildTaskMap) ->
		TGuildTaskMap1 = maps:remove(GuildId, TGuildTaskMap),
		TGuildTaskMap1
	end,
	NewGuildTaskMap = lists:foldl(F, GuildTaskMap, GuildIdList),
	NewState = State#guild_race_rank_state{guild_task = NewGuildTaskMap},
	NewState.

%% --------------------------------- db -----------------------------------------
db_save_race_rank_task(GuildId, TaskId, Progress, Status) ->
	Sql = io_lib:format(?insert_guild_race_rank_task, [GuildId, TaskId, Progress, Status]),
	db:execute(Sql),
	ok.

db_select_race_rank_task() ->
	Sql = io_lib:format(?select_guild_race_rank_task, []),
	db:get_all(Sql).

db_update_race_rank_task(GuildId, TaskId, Status) ->
	Sql = io_lib:format(?update_guild_race_rank_task, [Status, GuildId, TaskId]),
	db:execute(Sql),
	ok.

db_delete_race_rank_task(GuildId) ->
	Sql = io_lib:format(?delete_guild_race_rank_task, [GuildId]),
	db:execute(Sql),
	ok.
