%% --------------------------------------
%% desc  :最近聊天相关逻辑
%% module:relation_last_chat
%% author:hh
%% time  :19/11/05
%% --------------------------------------

-module(relation_last_chat).

-export([
    get_last_rela_list/1            %% 获取最近联系人列表信息
    ,get_last_rela_on_dict/1        %% 在进程字典中获取最近联系人列表信息
    ,get_last_rela_role_info/2      %% 获取最近联系人具体信息
    ,add_last_rela_list/2           %% 加入最近联系人列表
    ,update_last_rela_list/2        %% 更新最近联系人列表
    ,save_last_relas_on_dict/2      %% 更新最近联系人信息字典
    ,del_black_from_last_rela/2     %% 将拉黑的人从最近联系人中删除
    ,update_last_rela_on_db/3       %% 更新最近联系人数据库操作
    ]).

-include("role.hrl").
-include("relationship.hrl").
-include("common.hrl").

%% 是否是玩家自己的进程
is_self_pid(RoleId) ->
    Pid = misc:get_player_process(RoleId),
    Pid =:= self().

%% 获取最近联系人列表信息
get_last_rela_on_dict(RoleId) ->
    case is_self_pid(RoleId) of
        true ->
            case get(?LAST_RELA_LIST) of
                undefined ->
                    LastRelas = get_last_rela_on_db(RoleId),
                    save_last_relas_on_dict(RoleId, LastRelas),
                    LastRelas;
                Value -> Value
            end;
        _ -> []
    end.

%% 离线获取最近联系人信息
get_last_rela_on_db(RoleId) ->
    LastRelas = case db_get_last_relas_by_role_id(RoleId) of
        List = [_|_] -> [make_record(last_rela_chat, T) || T <- List];
        _ -> []
    end,
    LastRelas.

%% 保存最近联系人信息
save_last_relas_on_dict(RoleId, LastRelas) ->
    case is_self_pid(RoleId) of
        true -> put(?LAST_RELA_LIST, LastRelas);
        _ -> skip
    end.

%% 获取最近联系人具体信息
make_record(last_rela_chat, [RoleId, OtherRid, Time]) ->
    #last_rela_chat{role_id = RoleId, other_id = OtherRid, time = Time}.



%% 获取最近联系人具体信息
get_last_rela_role_info(RoleId, LastRelas) ->
    RelaList = lib_relationship:get_rela_on_dict(RoleId),
    get_one_last_rela_role_info(RelaList, LastRelas, []).

% get_last_rela_include_strange(RoleId, LastRelas) ->
%     RelaList = lib_relationship:get_rela_on_dict(RoleId),
%     get_last_rela_include_strange(RelaList, LastRelas, []).

get_one_last_rela_role_info(_RelaList, [], Sofar) -> Sofar;
get_one_last_rela_role_info(RelaList, [#last_rela_chat{other_id = OtherRid}|Rest], Sofar) ->
    case do_get_one_last_rela_role_info(RelaList, OtherRid) of
        false -> get_one_last_rela_role_info(RelaList, Rest, Sofar);
        _T -> 
        get_one_last_rela_role_info(RelaList, Rest, [_T|Sofar])
    end.

% get_last_rela_include_strange(_RelaList, [], Sofar) -> Sofar;
% get_last_rela_include_strange(RelaList, [#last_rela_chat{other_id = OtherRid, time = Time}|Rest], Sofar) ->
%     case do_get_one_last_rela_include_strange(RelaList, OtherRid, Time) of
%         false -> get_last_rela_include_strange(RelaList, Rest, Sofar);
%         _T -> get_last_rela_include_strange(RelaList, Rest, [_T|Sofar])
%     end.

do_get_one_last_rela_role_info(RelaList, OtherRid) ->
    case lib_role:get_role_show(OtherRid) of
        RoleInfo = #ets_role_show{} ->
            Rela = 
            case lists:keyfind(OtherRid, #rela.other_rid, RelaList) of
                R = #rela{} -> R;
                _ -> #rela{}
            end,
            % NewRoleInfo = fix_online_flag(RoleInfo, OtherRid),
            lib_relationship:make_up_friend_info(Rela, RoleInfo);
        _ -> false 
    end.

% do_get_one_last_rela_include_strange(RelaList, OtherRid, Time) ->
%     case lib_role:get_role_show(OtherRid) of
%         RoleInfo = #ets_role_show{} ->
%             Rela = 
%             case lists:keyfind(OtherRid, #rela.other_rid, RelaList) of
%                 R = #rela{} -> R;
%                 _ -> #rela{last_chat_time = Time}
%             end,
%             % NewRoleInfo = fix_online_flag(RoleInfo, OtherRid),
%             lib_relationship:make_up_friend_info(Rela, RoleInfo);
%         _ -> false
%     end.


%% 获取最近联系人列表信息
db_get_last_relas_by_role_id(RoleId) ->
    Sql = io_lib:format(?sql_get_last_relas_by_role_id, [RoleId]),
    db:get_all(Sql).

%% 删除最近联系人
db_del_last_rela_by_role_id(RoleId, OtherRid) ->
    Sql = io_lib:format(?sql_del_last_rela_by_role_id, [RoleId, OtherRid]),
    db:execute(Sql).



%% 获取最近联系人列表
get_last_rela_list(RoleId) ->
    LastRelas = get_last_rela_on_dict(RoleId),
    get_last_rela_role_info(RoleId, LastRelas).

%% 陌生人私聊时加入最近联系人列表
add_last_rela_list(RoleId, OtherRid) ->
    LastRelas = get_last_rela_on_dict(RoleId),
    NewLastRelas = 
    case lists:keyfind(OtherRid, #last_rela_chat.other_id, LastRelas) of
        LastRela = #last_rela_chat{} ->
            NewLastRela = LastRela#last_rela_chat{time = utime:unixtime()},
            lists:keystore(OtherRid, #last_rela_chat.other_id, LastRelas, NewLastRela);
        _ ->
            LastRela1 = #last_rela_chat{role_id = RoleId, other_id = OtherRid, time = utime:unixtime()},
            lists:keystore(LastRela1, #last_rela_chat.other_id, LastRelas, LastRela1)
    end,
    NewLastRelas1 = lists:sort(fun(#last_rela_chat{time = Time1}, #last_rela_chat{time = Time2}) -> Time1 > Time2 end, NewLastRelas),
    Len = length(NewLastRelas1),
    case Len > ?LAST_RELA_CHAT_LIMIT of
        true -> NewLastRelas2 = lists:sublist(NewLastRelas1, 1, ?LAST_RELA_CHAT_LIMIT); %% 前十个
        _ -> NewLastRelas2 = NewLastRelas1
    end,
    % ?ERR("~p", [NewLastRelas2]),
    DeleteLastRelas = NewLastRelas1 -- NewLastRelas2,
    save_last_relas_on_dict(RoleId, NewLastRelas2),
    %% 数据库更新操作
    update_last_rela_on_db(delete, DeleteLastRelas, RoleId),
    update_last_rela_on_db(replace, NewLastRelas2, RoleId),
    ok.
    % DataList = get_last_rela_include_strange(RoleId, NewLastRelas2),
    % {ok, BinData} = pt_140:write(14020, [DataList]),
    % lib_server_send:send_to_uid(RoleId, BinData).

%% 更新最近联系人列表
update_last_rela_list(RoleId, Rela = #rela{other_rid = OtherRid}) ->
    LastRelas = get_last_rela_on_dict(RoleId),
    NewLastRelas =
    case lists:keyfind(OtherRid, #last_rela_chat.other_id, LastRelas) of
        LastRela = #last_rela_chat{} ->
            NewLastRela = LastRela#last_rela_chat{time = Rela#rela.last_chat_time},
            lists:keystore(OtherRid, #last_rela_chat.other_id, LastRelas, NewLastRela);
        _ ->
            LastRela1 = #last_rela_chat{role_id = RoleId, other_id = OtherRid, time = Rela#rela.last_chat_time},
            lists:keystore(LastRela1, #last_rela_chat.other_id, LastRelas, LastRela1)
    end,
    NewLastRelas1 = lists:sort(fun(#last_rela_chat{time = Time1}, #last_rela_chat{time = Time2}) -> Time1 > Time2 end, NewLastRelas),
    Len = length(NewLastRelas1),
    case Len > ?LAST_RELA_CHAT_LIMIT of
        true -> NewLastRelas2 = lists:sublist(NewLastRelas1, 1, ?LAST_RELA_CHAT_LIMIT); %% 前十个
        _ -> NewLastRelas2 = NewLastRelas1
    end,
    DeleteLastRelas = NewLastRelas1 -- NewLastRelas2,
    save_last_relas_on_dict(RoleId, NewLastRelas2),
    %% 数据库更新操作
    update_last_rela_on_db(delete, DeleteLastRelas, RoleId),
    update_last_rela_on_db(replace, NewLastRelas2, RoleId);
update_last_rela_list(_RoleId, _) -> skip.

%% 更新最近联系人数据库操作
update_last_rela_on_db(_Type, [], _RoleId) -> skip;
update_last_rela_on_db(delete, [#last_rela_chat{other_id = OtherRid}|DeleteLastRelas], RoleId) ->
    db_del_last_rela_by_role_id(RoleId, OtherRid),
    update_last_rela_on_db(delete, DeleteLastRelas, RoleId);
update_last_rela_on_db(replace, LastRelas, _RoleId) ->
    Values = format_value_list(LastRelas, []),
    Values1 = string:join(Values, ", "),
    Sql = io_lib:format(?sql_replace_into_last_rela, [Values1]),
    db:execute(Sql).

format_value_list([], Sofar) -> Sofar;
format_value_list([#last_rela_chat{role_id = RoleId, other_id = OtherRid, time = Time}|Rest], Sofar) ->
    Sql = io_lib:format("(~p, ~p, ~p)", [RoleId, OtherRid, Time]),
    format_value_list(Rest, [Sql|Sofar]).


%% 将拉黑的人从最近联系人中删除
del_black_from_last_rela(RoleId, BlackId) ->
    LastRelas = get_last_rela_on_dict(RoleId),
    NewLastRelas = do_del_from_last_rela(RoleId, BlackId, LastRelas),
    save_last_relas_on_dict(RoleId, NewLastRelas),
    update_last_rela_info(RoleId, NewLastRelas).

update_last_rela_info(RoleId, NewLastRelas) ->
    LastRelaInfo = get_last_rela_role_info(RoleId, NewLastRelas),
    {ok, BinData} = pt_140:write(14016, [LastRelaInfo]), %% LastRelas = [_|_]
    lib_server_send:send_to_uid(RoleId, BinData).

do_del_from_last_rela(RoleId, BlackId, LastRelas) ->
    NewLastRelas = lists:keydelete(BlackId, #last_rela_chat.other_id, LastRelas),
    db_del_last_rela_by_role_id(RoleId, BlackId),
    NewLastRelas.