%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     离线托管-本服公会战
%%% @end
%%%-------------------------------------------------------------------
-module(offline_hosting_guild_war).
-author("liushl").

-include("server.hrl").
-include("common.hrl").
-include("attr.hrl").
-include("guild_war.hrl").
-include("scene.hrl").
-include("def_module.hrl").
-include("role.hrl").

%% API
-export([
    check_hosting/0,
    check_hosting_in_guild/1,
    host_behavior/3
]).

%% 活动开始30秒后，每3秒进5个人
%% 踢人在玩家结算后再踢人
check_hosting() ->
    mod_guild:apply_cast(?MODULE, check_hosting_in_guild, [self()]).

%% 公会进程判断情况
check_hosting_in_guild(From) ->
    AllGuild = lib_guild_data:get_guild_map(),
    Guild_Members = maps:fold(
        fun(GuildId, _, Temp) ->
            GuildMember = lib_guild_data:get_guild_member_map(GuildId),
            [{GuildId, maps:keys(GuildMember)}|Temp]
        end, [], AllGuild
    ),
    Now = utime:unixtime(),
    Pid = spawn(
        fun() -> check_hosting_by_role(Guild_Members, Now, 0) end
    ),
    From ! {register_host, Pid}.

check_hosting_by_role([], _, _) -> ok;
check_hosting_by_role([{_, []}|T], Now, Count) ->
    check_hosting_by_role(T, Now, Count);
check_hosting_by_role([{GuildId, [RoleId|TRole]}|TGuild], Now, Count) ->
    Res = offline_hosting:take_part_in(?MODULE, ?MOD_GUILD_WAR, RoleId, []),
    case Res =:= 1 of
        true  ->
            case Count > 3 of
                true  ->
                    NewCount = 0,
                    timer:sleep(5000);
                false ->
                    NewCount = Count + 1
            end,
            check_hosting_by_role([{GuildId, TRole}|TGuild], Now, NewCount);
        false ->
            check_hosting_by_role([{GuildId, TRole}|TGuild], Now, Count)
    end.

%% 状态：
%%                        进入场景
%%                         / |
%%                        / 死亡
%%                       / /   \
%%                      采集====采集提交

%% 托管上线事件->切场景->前往采集采集
host_behavior(login, Player, _) ->
    {ok, Player1} = guild_war_api:enter_scene(Player, 0),
    {ok, Player2} = pp_scene:handle(12002, Player1, []),
    {ok, Player3} = go_to_collection(Player2),
    {ok, Player3};

%% 采集->提交
host_behavior(collection, Player, [TargetX, TargetY]) ->
    CollectId = ?GUILD_WAR_LOW_QUALITY_MATERIALS,
    Player1 = guild_war_api:role_into_convoy_state(Player, CollectId),
    DestinationBehavior = commit,
    {ok, Player2} = offline_hosting:host_behavior_move(Player1, TargetX, TargetY, DestinationBehavior, [], 20000),
    {ok, Player2};

%% 提交->前往采集采集
host_behavior(commit, Player, _) ->
    CollectId = ?GUILD_WAR_LOW_QUALITY_MATERIALS,
    Player1 = guild_war_api:collect_commit_do(Player, CollectId),
    {ok, Player2} = go_to_collection(Player1),
    {ok, Player2};

%% 死亡后安全区复活-15秒
host_behavior(die, Player, _) ->
    {ok, Player1} = offline_hosting:host_behavior_delay(Player, revive, [], 15000),
    {ok, Player1};

%% 复活->前往采集
host_behavior(revive, Player, _) ->
    #player_status{battle_attr = #battle_attr{hp_lim = Hp} = BA} = Player,
    %% 通知离开场景
    lib_scene:leave_scene(Player),
    [X, Y] = lib_scene:get_born_xy(Player#player_status.scene),
    Player1 = Player#player_status{x = X, y = Y, battle_attr = BA#battle_attr{hp = Hp}},
    %% 加载场景
    {ok, Player2} = pp_scene:handle(12002, Player1, []),
    %% 前往采集
    {ok, Player3} = go_to_collection(Player2),
    {ok, Player3};

host_behavior(_Behavior, Player, _Any) ->
    {ok, Player}.

%% 前往采集-提交
go_to_collection(Player) ->
    case data_scene:get(?GUILD_WAR_SCENE) of
        #ets_scene{mon = Mons, npc = Npc} ->
            %% 确定采集目标
            AllMonsPositions = [{X, Y} || [_, X, Y, _, _] <- Mons],
            {TargetX, TargetY} = urand:list_rand(AllMonsPositions),
            %% 确定提交目标
            AllNpcPosition = [{X, Y} || [_, X, Y, _] <- Npc],
            {CollectX, CollectY} = urand:list_rand(AllNpcPosition),
            DestinationBehavior = collection,
            DestinationArg = [CollectX, CollectY],
            {ok, Player1} = offline_hosting:host_behavior_move(Player, TargetX, TargetY, DestinationBehavior, DestinationArg, 5000),
            {ok, Player1};
        _ ->
            ?ERR("xy error:~p", [Player#player_status.scene]),
            {ok, Player}
    end.