%% -------------------------------------------
%% @desc        :社团跑环协助
%% @module      :guild_support_run_assist.erl
%% @author      :hh
%% @time        :21/04/16
%% -------------------------------------------

-module (guild_support_run_assist).

-export ([
    make_content/1
    ,player_enter_game_player/3
    ]).

-export ([
    finish_support/4
    ,cancel_support/4
    ,expire_support/3
    ,update_support_status/3
    ,get_assist_type_by_support_cfg_id/1
    ,get_support_cfg_id_by_assist_type/1

    ,guild_support_proc_update_support_status/3
    
    ,role_trigger_cancel_assist/4
    ,role_expire_cancel_run_assist/3
    ]).

-include ("guild.hrl").
-include ("guild_run_assist.hrl").
-include ("figure.hrl").
-include ("server.hrl").
-include ("predefine.hrl").
-include ("def_module.hrl").
-include ("def_act_label.hrl").
-include ("errcode.hrl").
-include ("common.hrl").

player_enter_game_player(Player, SupportInfo, _ArgsList) ->
    #player_status{id = RoleId, figure = #figure{guild_id = GuildId}, guild = StatusGuild} = Player,
    #guild_support{
        support_sid = SupportSid,
        support_cfg_id = SupportCfgId,
        ask_id = AskerId
        } = SupportInfo,
    AssistType = get_assist_type_by_support_cfg_id(SupportCfgId),
    if AssistType == ?GUILD_RUN_ASSIST_BOSS ->
            NewStatusGuild = StatusGuild#status_guild{
                support_id = SupportSid
                ,support_leader_id = AskerId
                ,support_cfg_id    = SupportCfgId
            };
        true ->
            NewStatusGuild = StatusGuild#status_guild{
                support_id = SupportSid, is_in_support = 1
                ,support_leader_id = AskerId
                ,support_cfg_id    = SupportCfgId
            }
    end,
    %% 更改头标
    AssistType =/= ?GUILD_RUN_ASSIST_QUIZ andalso lib_scene:change_act_label(RoleId, ?ACT_LABEL_SUPPORT, 1),
    lib_server_send:send_to_uid(RoleId, pt_400, 40052, [?SUCCESS, SupportSid, SupportCfgId]),
    if AssistType =/= 0 ->
            guild_run_assist:take_run_assist(RoleId, GuildId, SupportSid, AssistType);
        true ->
            skip
    end,
    {ok, Player#player_status{guild = NewStatusGuild}}.

make_content(GameInfo) ->
    Content = {guild_run_assist, GameInfo},
    Content.

%% 成功完成协助
finish_support(Sid, GuildId, AssistType, AskId) ->
    GuildSupportMap = lib_guild_support_mod:get_guild_support_map(GuildId),
    F = fun(SupportId, GuildSupport) ->
        case GuildSupport of
            #guild_support{module = ?MODULE, ask_id = AskId} when Sid == SupportId ->
                lib_guild_support_mod:asker_finish_support(AskId, GuildId, SupportId, [AskId]),
                lib_player:apply_cast(AskId, ?APPLY_CAST_SAVE, guild_run_assist, role_finish_support, [AssistType, SupportId]);
            _ ->
                ignore
        end end,
    maps:map(F, GuildSupportMap),
    ok.

%% 因任务失败或下线等原因,协助者终止了协助
cancel_support(CancelType, SubModule, Supporter, SupportId) ->
    lib_player:apply_cast(Supporter, ?APPLY_CAST_SAVE, ?MODULE, role_trigger_cancel_assist, [CancelType, SubModule, SupportId]),
    ok.

%% 超时协助单处理
%% IsExpire 是否协助单被取消,还是仅取消协助者协助状态
expire_support(GuildId, SupportId, IsExpire) ->
    GuildSupportMap = lib_guild_support_mod:get_guild_support_map(GuildId),
    case maps:get(SupportId, GuildSupportMap, false) of
        GuildSupport = #guild_support{ask_id = Asker, support_cfg_id = CfgId, support_role_list = RoleList} ->
            case data_guild:get_guild_support_cfg(CfgId) of
                #base_guild_support{module_id = ?MOD_GUILD_RUN_ASSIST, sub_mod_id = SubModule} ->
                    F1 = fun(TSupporterId) ->
                        lib_player:apply_cast(TSupporterId, ?APPLY_CAST_SAVE, ?MODULE, role_expire_cancel_run_assist, [SubModule, SupportId])
                    end,
                    lists:map(F1, RoleList),
                     if
                        IsExpire -> %% 取消单
                            lib_player:apply_cast(Asker, ?APPLY_CAST_SAVE, guild_run_assist, expire_cancel_run_asist, [SubModule, SupportId]),
                            NewGuildSupportMap = maps:remove(SupportId, GuildSupportMap);
                        true -> %% 修改协助者列表
                            NewGuildSupportMap = maps:put(SupportId, GuildSupport#guild_support{support_role_list = []}, GuildSupportMap)
                    end,
                    lib_guild_support_mod:save_guild_support_map(GuildId, NewGuildSupportMap),
                    %% 通知玩家当前的协助列表长度(GuildSupport直接用空数据处理)
                    mod_guild:apply_cast_guild_member(GuildId, 1, lib_guild_support_mod, send_to_guild_member,
                        [#guild_support{}, maps:size(NewGuildSupportMap)]
                    );
                _ ->
                    skip
            end;
        _ ->
            skip
    end,
    ok.

%% 协助者无人接单&被协助者协助时 因超时被系统取消
role_expire_cancel_run_assist(Player, SubModule, SupportSid) ->
    NewPlayer = lib_guild_support_mod:reset_player_support_status(Player),
    {ok, NewPlayer1} = guild_run_assist:expire_cancel_run_asist(NewPlayer, SubModule, SupportSid),
    {ok, NewPlayer1}.

%% 协助者任务失败或其他原因 触发协助取消
role_trigger_cancel_assist(Player, CancelType, SubModule, SupportSid) ->
    if CancelType == active_cancel -> %% 主动取消需通知通用协助额外处理,下线通用协助会检测处理,无需再做通知
            NewPlayer = lib_guild_support_mod:cancel_support(Player);
        true ->
            NewPlayer = Player
    end,
    {ok, NewPlayer1} = guild_run_assist:role_trigger_cancel_assist(NewPlayer, SubModule, SupportSid),
    {ok, NewPlayer1}.

get_assist_type_by_support_cfg_id(5) -> ?GUILD_RUN_ASSIST_QUIZ;
get_assist_type_by_support_cfg_id(6) -> ?GUILD_RUN_ASSIST_BOSS;
get_assist_type_by_support_cfg_id(_) -> 0.


get_support_cfg_id_by_assist_type(?GUILD_RUN_ASSIST_QUIZ) -> 5;
get_support_cfg_id_by_assist_type(?GUILD_RUN_ASSIST_BOSS) -> 6;
get_support_cfg_id_by_assist_type(_) -> 0.

update_support_status(GuildId, Sid, KvList) ->
    mod_guild_support:apply_cast(?MODULE, guild_support_proc_update_support_status, [GuildId, Sid, KvList]),
    ok.

guild_support_proc_update_support_status(GuildId, SupportId, KvList) ->
   GuildSupportMap = lib_guild_support_mod:get_guild_support_map(GuildId),
   case maps:get(SupportId, GuildSupportMap, false) of
        GuildSupport = #guild_support{support_cfg_id = CfgId, extra_data = ExtraData} ->
            case data_guild:get_guild_support_cfg(CfgId) of
                #base_guild_support{module_id = ?MOD_GUILD_RUN_ASSIST} ->
                    NewExtraData = lists:foldl(fun({K, V}, TempExtraData) -> 
                        lists:keystore(K, 1, TempExtraData, {K, V})
                    end, ExtraData, KvList),
                    NewGuildSupport = GuildSupport#guild_support{extra_data = NewExtraData},
                    NewGuildSupportMap = maps:put(SupportId, NewGuildSupport, GuildSupportMap),
                    lib_guild_support_mod:save_guild_support_map(GuildId, NewGuildSupportMap),
                    ok;
                _ ->
                    skip
            end;
        _A ->
            skip
    end.