%%%------------------------------------
%%% @Module  : lib_relationship_api
%%% @Author  :  xiaoxiang
%%% @Created :  2016-12-14
%%% @Description: 社交api
%%%------------------------------------

-module(lib_relationship_api).

-include("server.hrl").
-include("figure.hrl").
-include("errcode.hrl").
-include("relationship.hrl").
-include("vip.hrl").
-include("predefine.hrl").
-include("common.hrl").
-include("rec_event.hrl").
-include("def_event.hrl").
-include("scene.hrl").
-include("battle.hrl").
-include("attr.hrl").
-include("def_module.hrl").
-include("def_vip.hrl").
-include("team.hrl").
-include("dungeon_multi.hrl").
-include("flower.hrl").
-include("mate.hrl").

-export([
        handle_event/2
        , get_intimacy/2                    %% 获取玩家亲密度
        , get_rela_and_intimacy_online/2    %% 获得ID列表的关系和亲密度 在线 玩家自身进程才能获得
        , get_rela_and_intimacy/2           %% 获得ID列表的关系和亲密度 离线要查询数据库，慎用
        , get_rela_and_intimacy_offline/2   %% 获得ID列表的关系和亲密度 离线
        , send_rela_view_info/6
        , event_trigger/1                   %% 触发增加好友亲密度
        , clean_each_other_intimacy/2       %% 清空双方的亲密度
        , get_rela_view_info_cls/7
        , get_rela_view_info_tar/6
    ]).
%% 上下线事件（玩家上下线需要派发通知给好友）
handle_event(Player, #event_callback{type_id = ?EVENT_ONLINE_FLAG, data = OnlineFlag}) when is_record(Player, player_status) ->
    #player_status{id = RoleId, figure = Figure, online = OldOnlineFlag} = Player,
    if
        OnlineFlag == ?ONLINE_ON ->
            lib_relationship:role_change_online_status(RoleId, Figure, OnlineFlag);
        OldOnlineFlag == ?ONLINE_ON andalso OnlineFlag == ?ONLINE_OFF ->
            lib_relationship:role_change_online_status(RoleId, Figure, OnlineFlag);
        true -> skip
    end,
    {ok, Player};
%% 私聊更新双方的最后通信时间
handle_event(Player, #event_callback{type_id = ?EVENT_CHAT_PRIVATE, data = PrivateChatUid}) when is_record(Player, player_status) ->
    #player_status{id = RoleId} = Player,
    lib_relationship:update_last_ctime_each_one(RoleId, PrivateChatUid, utime:unixtime()),
    {ok, Player};
%% 上线切换场景之后统计一次好友和羁绊数量
handle_event(Player, #event_callback{type_id = ?EVENT_CLIENT_LOGIN_SUCCESS}) when is_record(Player, player_status) ->
    #player_status{id = RoleId, mate = RoleMate} = Player,
    #role_mate{mate_list = MateList} = RoleMate,
    lib_achievement_api:mate_event(Player, erlang:length(MateList)),
    lib_seven_days_goal:finish_task(RoleId, ?MOD_MATE, 1, erlang:length(MateList), true),
    RelaList = lib_relationship:get_rela_on_dict(RoleId),
    Filter = fun(TRela) -> TRela#rela.rela_type =:= ?RELA_TYPE_FRIEND end,
    FriendList = lists:filter(Filter, RelaList),
    lib_achievement_api:add_friend_event(Player, erlang:length(FriendList)),
    {ok, Player};
handle_event(Player, #event_callback{}) ->
    {ok, Player}.

%% 获得ID列表的关系和亲密度 在线 玩家自身进程才能获得
get_rela_and_intimacy_online(RoleId, IdList) ->
    lib_relationship:get_rela_and_intimacy_online(RoleId, IdList).

%% 获得ID列表的关系和亲密度 离线要查询数据库，慎用
get_rela_and_intimacy(RoleId, IdList) ->
    lib_relationship:get_rela_and_intimacy(RoleId, IdList).

%% 获得ID列表的关系和亲密度 离线
get_rela_and_intimacy_offline(RoleId, IdList) ->
    lib_relationship:get_rela_and_intimacy_offline(RoleId, IdList).

%% 获取玩家亲密度
get_intimacy(RoleId, OtherRid) ->
    lib_relationship:get_intimacy(RoleId, OtherRid).

%% 清空双方的亲密度
clean_each_other_intimacy(RoleId, OtherRid) ->
    lib_relationship:clean_each_other_intimacy(RoleId, OtherRid).

%% 触发增加双方亲密度
event_trigger({kill_mon, Mid, MonKind, BossType, BLWhos}) ->
    case data_rela:get_intimacy_obtain_cfg(?INTIMACY_TYPE_MON) of
        #intimacy_obtain_cfg{intimacy = Intimacy, trigger_obj = ObjList} when is_list(ObjList) ->
            case lists:member({MonKind, BossType}, ObjList) of
                true -> %% 判断怪物类型是否增加亲密度
                    F = fun(T, Map) ->
                        case T of
                            #mon_atter{node = Node, team_id = TeamId, id = RoleId} ->
                                TeamMap = maps:get(Node, Map, #{}),
                                RoleL = maps:get(TeamId, TeamMap, []),
                                NewTeamMap = maps:put(TeamId, [RoleId|RoleL], TeamMap),
                                maps:put(Node, NewTeamMap, Map);
                            _ -> Map
                        end
                    end,
                    Map = lists:foldl(F, #{}, BLWhos),
                    List = maps:to_list(Map),
                    IsCls = util:is_cls(),
                    F1 = fun({Node, TeamMap}) ->
                        case IsCls of
                            true ->
                                clusters_center:apply_cast(Node, lib_relationship_api, trigger_intimacy, [{kill_mon, Mid, TeamMap, Intimacy}]);
                            false ->
                                trigger_intimacy({kill_mon, Mid, TeamMap, Intimacy})
                        end
                    end,
                    lists:foreach(F1, List);
                _ -> skip
            end;
        _ -> skip
    end;
event_trigger({pass_dun, DunId, TeamMap}) ->
    case data_rela:get_intimacy_obtain_cfg(?INTIMACY_TYPE_DUN) of
        #intimacy_obtain_cfg{intimacy = Intimacy, trigger_obj = ObjList} when is_list(ObjList) ->
            case lists:member(DunId, ObjList) of
                true ->
                    trigger_intimacy({pass_dun, DunId, TeamMap, Intimacy});
                _ -> skip
            end;
        _ -> skip
    end;
event_trigger(_) -> skip.
%% 增加亲密度
trigger_intimacy({kill_mon, Mid, TeamMap, Intimacy}) ->
    TeamRoleL = maps:values(TeamMap),
    ExtraMsg = [{kill_mon, Mid}],
    F = fun(RoleL) ->
        lib_relationship:trigger_intimacy_add(RoleL, Intimacy, ?INTIMACY_TYPE_MON, 0, ExtraMsg)
    end,
    lists:foreach(F, TeamRoleL);
trigger_intimacy({pass_dun, DunId, TeamMap, Intimacy}) ->
    TeamRoleL = maps:values(TeamMap),
    ExtraMsg = [{pass_dun, DunId}],
    F = fun(RoleL) ->
        lib_relationship:trigger_intimacy_add(RoleL, Intimacy, ?INTIMACY_TYPE_DUN, 0, ExtraMsg)
    end,
    lists:foreach(F, TeamRoleL);
trigger_intimacy(_) -> skip.


get_rela_view_info_cls(Node, RoleId, OtherRid, RoleServer, RelaType, Intimacy, IsLocal) ->
    case clusters_center:check_node_connect(RoleServer) of
        true ->
            clusters_center:apply_cast(RoleServer, ?MODULE, get_rela_view_info_tar, [OtherRid, Node, RoleId, RelaType, Intimacy, IsLocal]);
        _ ->
            {ok, BinData} = pt_140:write(14010, [?ERRCODE(err140_14_not_online), OtherRid, #figure{}, RelaType, 0, 0, Intimacy, IsLocal, 0, 0]),
            lib_server_send:send_to_uid(Node, RoleId, BinData)
    end.

%% 目标服执行
get_rela_view_info_tar(OtherRid, FromNode, FromId, RelaType, Intimacy, IsLocal) ->
    OtherPid = misc:get_player_process(OtherRid),
    case misc:is_process_alive(OtherPid) of
        true ->
            lib_player:apply_cast(OtherRid, ?APPLY_CAST_STATUS, lib_relationship_api, send_rela_view_info, [FromNode, FromId, RelaType, Intimacy, IsLocal]);
        false ->
            WeekCharm = lib_flower:db_get_role_week_charm(OtherRid),
            #figure{power = Power} = Figure = lib_role:get_role_figure(OtherRid),
            SvrNum = config:get_server_num(),
            {ok, BinData} = pt_140:write(14010, [?SUCCESS, OtherRid, Figure, RelaType, Power, WeekCharm, Intimacy, IsLocal, 0, SvrNum]),
            clusters_node:apply_cast(lib_server_send, send_to_uid, [FromNode, FromId, BinData])
            % lib_server_send:send_to_uid(FromNode, FromId, BinData)
    end.

%%--------------------------------------------------
%% 发送玩家交互面板信息(被请求信息的玩家进程)
%% 点击人物头像弹出的那个
%% @param  Player   被请求PS
%% @param  RelaType 请求者与自己的关系类型
%% @return          description
%%--------------------------------------------------
send_rela_view_info(Player, FromNode, RequesterId, RelaType, Intimacy, IsLocal) ->
    #player_status{id = RoleId, flower = #flower{week_charm = WeekCharm}, server_num = SvrNum,
        figure = Figure, combat_power = Combat,  team = #status_team{team_id = TeamId}} = Player,
    if IsLocal == 0 ->
            {ok, BinData} = pt_140:write(14010, [?SUCCESS, RoleId, Figure, RelaType, Combat, WeekCharm, Intimacy, IsLocal, TeamId, SvrNum]),
            lib_server_send:send_to_uid(FromNode, RequesterId, BinData);
        true ->
            {ok, BinData} = pt_140:write(14010, [?SUCCESS, RoleId, Figure, RelaType, Combat, WeekCharm, Intimacy, IsLocal, 0, SvrNum]),
            clusters_node:apply_cast(lib_server_send, send_to_uid, [FromNode, RequesterId, BinData])
    end.
