%%%------------------------------------
%%% @Module  : lib_rush_rank_mod
%%% @Author  :  xiaoxiang
%%% @Created :  2016-11-17
%%% @Description: 通用榜单
%%%------------------------------------

-module(lib_rush_rank_mod).


-export([
    init/0
    , refresh_rush_rank/4
    , send_rank_list/6
]).

-compile(export_all).

-include("errcode.hrl").
-include("language.hrl").
-include("rush_rank.hrl").
-include("common.hrl").
-include("figure.hrl").
-include("role.hrl").
-include("goods.hrl").
-include("custom_act.hrl").
-include("def_module.hrl").
-include("def_fun.hrl").
-include("server.hrl").

make_record(rush_rank_role, [RankType, SubType, RoleId, Value, Value2, Value3,Value4,Value5,Time]) ->
    #rush_rank_role{
        role_key  = {RankType, SubType, RoleId},
        rank_type = RankType,
        sub_type  = SubType,
        role_id   = RoleId,
        value     = Value,
        value2    = Value2,
        value3    = Value3,
        value4    = Value4,
        value5    = Value5,
        time      = Time
    }.

init() ->
    %% 个人榜单
    List = db_rush_rank_role_select(),
    RoleList = [make_record(rush_rank_role, T) || T <- List],
    RankMaps = get_standard_sort_rank_maps(rush_rank_role, RoleList),
    RoleLimitList = clean_redundant_rank_data_from_db(RankMaps),
    RankLimit = maps:from_list(RoleLimitList),

    List1 = db_rush_rank_goal_select(),
    F = fun([RankType, SubType, RoleId, GoalId, RewardState], GoalList) ->
        case lists:keyfind({RankType, SubType, RoleId}, 1, GoalList) of
            {_, GoalStateList} ->
                NewGoalStateList = lists:keystore(GoalId, 1, GoalStateList, {GoalId, RewardState});
            _ ->
                NewGoalStateList = [{GoalId, RewardState}]
        end,
        lists:keystore({RankType, SubType, RoleId}, 1, GoalList, {{RankType, SubType, RoleId}, NewGoalStateList})
    end,
    GoalList = lists:foldl(F, [], List1),
    GoalMaps = maps:from_list(GoalList),
    #rush_rank_state{rank_maps = RankMaps, rank_limit = RankLimit, goal_maps = GoalMaps}.

%% 获得标准排序Maps(被截取了长度) Key:RankType Value:[#rush_rank_role{}]
get_standard_sort_rank_maps(rush_rank_role, RoleList) ->
    MapsKeyList = get_sort_rank_maps(rush_rank_role, RoleList),
    F = fun({{RankType, SubType}, RankList}) ->
        MaxRankLen = lib_rush_rank:get_max_len(RankType),
        NewRankList = lists:sublist(RankList, MaxRankLen),
        {{RankType, SubType}, NewRankList}
        end,
    NewKeyList = lists:map(F, MapsKeyList),
    NewMaps = maps:from_list(NewKeyList),
    NewMaps.

%% 分类到Maps,然后对Maps的Value排序 Key:RankType Value:[#rush_rank_role{}]
get_sort_rank_maps(rush_rank_role, RoleList) ->
    F = fun(#rush_rank_role{rank_type = RankType, sub_type = SubType} = RankRole, Maps) ->
        case maps:get({RankType, SubType}, Maps, false) of
            false -> NewList = [RankRole];
            List -> NewList = [RankRole | List]
        end,
        maps:put({RankType, SubType}, NewList, Maps)
        end,
    Maps = lists:foldl(F, maps:new(), RoleList),
    NewKeyList = sort_rank_maps(Maps),
    NewKeyList.

%% 对Maps的Value排序
sort_rank_maps(Maps) ->
    MapsKeyList = maps:to_list(Maps),
    F = fun({{RankType, SubType}, List}) ->
        RankList = sort_rank_list(List),
        {{RankType, SubType}, RankList}
        end,
    NewKeyList = lists:map(F, MapsKeyList),
    NewKeyList.

%% 排序并且赋予排名
sort_rank_list(List) ->
    F = fun(A, B) ->
        if
            is_record(A, rush_rank_role) ->
                #rush_rank_role{rank_type=RankType}=A,
                case lists:member(RankType,?RANK_TYPE_FOSTER_GRADE_LIST) of
                    true-> %%进阶比较阶 星 战力
                        if
                            A#rush_rank_role.value > B#rush_rank_role.value -> true;
                            A#rush_rank_role.value == B#rush_rank_role.value ->
                                if
                                    A#rush_rank_role.value2 > B#rush_rank_role.value2 ->true;
                                    A#rush_rank_role.value2 == B#rush_rank_role.value2 ->
                                        A#rush_rank_role.value3 >= B#rush_rank_role.value3;
                                    true->false
                                end;
                            true ->
                                false
                        end;
                    _ when RankType == ?RANK_TYPE_RUSH_WARSOUL-> %% 战魂先比战力，再比星术
                        if
                            A#rush_rank_role.value > B#rush_rank_role.value -> true;
                            A#rush_rank_role.value == B#rush_rank_role.value ->
                                if
                                    A#rush_rank_role.value2 > B#rush_rank_role.value2 ->true;
                                    A#rush_rank_role.value2 == B#rush_rank_role.value2 ->
                                        A#rush_rank_role.time =< B#rush_rank_role.time;
                                    true->false
                                end;
                            true -> false
                        end;
                    _->
                        if
                            A#rush_rank_role.value > B#rush_rank_role.value -> true;
                            A#rush_rank_role.value == B#rush_rank_role.value ->
                                A#rush_rank_role.time =< B#rush_rank_role.time;
                            true -> false
                        end
                end;
            true ->
                false
        end
        end,
    NewList = lists:sort(F, List),

    TmpRankList = set_rank(NewList, [], 1),
    lists:reverse(TmpRankList).

set_rank([], RankList, _NowRank) -> RankList;
set_rank([Member|MemberList], RankList, NowRank) ->
    case Member of
        #rush_rank_role{rank_type = RankType, value = Value} ->
            RankLimit = lib_rush_rank:get_rank_limit_by_rank(RankType, NowRank),
            if
                Value >= RankLimit -> %% 符合条件
                    NewMember = Member#rush_rank_role{rank = NowRank},
                    NewRankList = [NewMember | RankList],
                    set_rank(MemberList, NewRankList, NowRank + 1);
                true ->
                    set_rank([Member|MemberList], RankList, NowRank + 1)
            end;
        _ ->
            set_rank(MemberList, RankList, NowRank)
    end.

%% 清理数据库的冗余数据,防止数据过多, 更新Limit值
clean_redundant_rank_data_from_db(RankMaps) ->
    MapsKeyList = maps:to_list(RankMaps),
    F = fun
        ({{RankType, SubType}, []}) ->
            Limit = lib_rush_rank:get_rank_limit(RankType),
            {{RankType, SubType}, Limit};
        ({{RankType, SubType}, RankList}) ->
            Limit = lib_rush_rank:get_rank_limit(RankType),
            RankMax = lib_rush_rank:get_max_len(RankType),
            case length(RankList) >= RankMax of
                true ->
                    #rush_rank_role{value = Value} = lists:last(RankList),
                    db_rush_rank_delete_by_value(RankType, SubType, Value),
                    {{RankType, SubType}, max(Value, Limit)};
                false ->
                    {{RankType, SubType}, Limit}
            end
        end,
    lists:map(F, MapsKeyList).

%% @param [{RankType, RushRankRole}]
refresh_rush_rank_by_list(State, List) ->
    %?PRINT("~p~n", [List]),
    F = fun({{RankType, SubType}, CommonRank}, TmpState) ->
        {ok, NewTmpState} = refresh_rush_rank(TmpState, RankType, SubType, CommonRank),
        NewTmpState
        end,
    NewState = lists:foldl(F, State, List),
    {ok, NewState}.

%% 刷新榜单
refresh_rush_rank(State, RankType, SubType, RushRankRole) ->
    #rush_rank_state{
        rank_maps  = RankMaps,
        rank_limit = RankLimit,
        goal_maps  = GoalMaps
    } = State,
    #rush_rank_role{
        role_id = RoleId
    } = RushRankRole,
    RankList = maps:get({RankType, SubType}, RankMaps, []),
    % 更新目标奖励领取状态
    GoalIds = data_rush_rank:get_goal_reward_ids(RankType),
    DefGoalList = [{Id, ?NOT_REWARD} || Id <- GoalIds],
    GoalList = maps:get({RankType, SubType, RoleId}, GoalMaps, DefGoalList),
    Fun = fun({GoalId, RewardState}) ->
        %% 已完成或已达成状态 不用根据值来更新状态
        if
            RewardState == ?NOT_REWARD ->
                NewRewardState = lib_rush_rank:get_new_reward_state(RankType, RushRankRole, GoalId);
            true ->
                NewRewardState = RewardState
        end,
        {GoalId, NewRewardState}
    end,
    NewGoalList = lists:map(Fun, GoalList),
    case NewGoalList =:= GoalList of
        true -> NewGoalMaps = GoalMaps;
        _ ->
            NewGoalMaps = maps:put({RankType, SubType, RoleId}, NewGoalList, GoalMaps),
            [db_rush_rank_goal_save(RankType, SubType, RoleId, GoalId, NewRewardState) || {GoalId, NewRewardState} <- NewGoalList],
            %% 奖励状态改变 主动推送给客户端
            send_goal_list(State#rush_rank_state{goal_maps = NewGoalMaps}, SubType, RoleId)
    end,
    {NewRankList, NewRankLimit} = do_refresh_rush_rank_help(RankList, RankType, SubType, RushRankRole, RankLimit),
    NewRankMaps = maps:put({RankType, SubType}, NewRankList, RankMaps),
    NewState = State#rush_rank_state{rank_maps = NewRankMaps, rank_limit = NewRankLimit, goal_maps = NewGoalMaps},
    {ok, NewState}.


%% 先判断list中是否存在key和value都相等的玩家，存在则跟新数据，不存在则将其进行队列排序：将其与队
%% 尾比较，若小于队尾并且队列长度大于最长长度，则丢弃，否则将其加入队列，排序并保证队列长度为最大
%% 队列长度，发送数据的时候，先截取显示长度，再判断是否满足limit，满足条件的才加入发送队列。
%% 时刻保证，排序之后队列和数据库保存的数据为整个服的前N，然后在这之中选择发送、

do_refresh_rush_rank_help(RankList, RankType, SubType, RushRankRole, RankLimit) ->
    #rush_rank_role{role_key = RoleKey, value = Value,value2 = Value2, value3=Value3} = RushRankRole,
    case lists:member(RankType,?RANK_TYPE_FOSTER_GRADE_LIST) of
        true->
            case lists:keyfind(RoleKey, #rush_rank_role.role_key, RankList) of
                #rush_rank_role{value = OldValue,value2=OldValue2,value3=OldValue3} when Value /= OldValue orelse Value2 /= OldValue2 orelse Value3 > OldValue3->
                    do_refresh_rush_rank_help2(RankList, RankType, SubType, RushRankRole, RankLimit);
                #rush_rank_role{}->
                    {RankList, RankLimit};
                _ ->
                    do_refresh_rush_rank_help2(RankList, RankType, SubType, RushRankRole, RankLimit)
            end;
        _->
            case lists:keyfind(RoleKey, #rush_rank_role.role_key, RankList) of
                #rush_rank_role{value = OldValue} when Value =< OldValue ->
                    {RankList, RankLimit};
                _ ->
                    do_refresh_rush_rank_help2(RankList, RankType, SubType, RushRankRole, RankLimit)
            end
    end.

do_refresh_rush_rank_help2(RankList, RankType, SubType, RushRankRole, RankLimit) ->
    MaxRankLen = lib_rush_rank:get_max_len(RankType),
    Limit = lib_rush_rank:get_rank_limit(RankType),
    LastValue = max(maps:get({RankType, SubType}, RankLimit, Limit), Limit),
    case RankList == [] of
        true ->
            if
                RushRankRole#rush_rank_role.value >= LastValue ->
                    db_rush_rank_role_save(RushRankRole),
                    NewRankList2 = [RushRankRole#rush_rank_role{rank = 1}],
                    NewRankList3 = sort_rank_list(NewRankList2),
                    {NewRankList3, RankLimit};
                true ->
                    NewRankList2 = [],
                    {NewRankList2, RankLimit}
            end;
        false ->
            IsExistKey = lists:keymember(RushRankRole#rush_rank_role.role_key, #rush_rank_role.role_key, RankList),
            #rush_rank_role{role_key = RoleKey, value = Value} = RushRankRole,
            %% 是否需要排序
            case Value < LastValue andalso (not IsExistKey) of
                true ->
                    NewRankList2 = RankList,
                    {NewRankList2, RankLimit};
                false ->
                    %% 内存和数据库存储
                    NewRankList = lists:keystore(RoleKey, #rush_rank_role.role_key, RankList, RushRankRole),
                    db_rush_rank_role_save(RushRankRole),
                    %% 排序
                    NewRankList2 = sort_rank_list(NewRankList),
                    case length(NewRankList2) > MaxRankLen of
                        true -> LeftRankList = lists:nthtail(MaxRankLen, NewRankList2);
                        false -> LeftRankList = []
                    end,
                    %% 清理冗余数据,这样修改插入数据效率会提高
                    [db_rush_rank_delete_by_id(RankType, SubType, TmpRoleId) || #rush_rank_role{role_id = TmpRoleId} <- LeftRankList],
                    %% 返回数据
                    LastList = lists:sublist(NewRankList2, MaxRankLen),
                    case LeftRankList of
                        [] ->
                            NewLastValue = LastValue;
                        _ ->
                            case LastList of
                                [] -> LastRankRole = #rush_rank_role{};
                                _ -> LastRankRole = lists:last(LastList)
                            end,
                            #rush_rank_role{value = TempLastValue} = LastRankRole,
                            NewLastValue = max(TempLastValue, LastValue)
                    end,
                    NewRankLimit = maps:put({RankType, SubType}, NewLastValue, RankLimit),
                    {LastList, NewRankLimit}
            end
    end.

%% 发送目标奖励状态列表
send_goal_list(State, SubType, RoleId) ->
    #rush_rank_state{goal_maps = GoalMaps} = State,
    %% 榜单类型根据开服天数排序 对应客户端的顺序
    F = fun(A, B) ->
        case data_rush_rank:get_rush_rank_cfg(A) of
            #base_rush_rank{start_day = StDayA} -> skip;
            _ ->
                % ?ERR("rush rank config err!~n", []),
                StDayA = 99999
        end,
        case data_rush_rank:get_rush_rank_cfg(B) of
            #base_rush_rank{start_day = StDayB} -> skip;
            _ ->
                % ?ERR("rush rank config err!~n", []),
                StDayB = 99999
        end,
        StDayA < StDayB
        end,
    SortTypeL = lists:sort(F, data_rush_rank:get_id_list()),
    F2 = fun(RankType, SendList) ->
        GoalIds = data_rush_rank:get_goal_reward_ids(RankType),
        DefGoalList = [{Id, ?NOT_REWARD} || Id <- GoalIds],
        GoalList = maps:get({RankType, SubType, RoleId}, GoalMaps, DefGoalList),
        StDay = case data_rush_rank:get_rush_rank_cfg(RankType) of
                    #base_rush_rank{start_day = TmpStDay} -> TmpStDay;
                    _ -> 99999
                end,
        GoalSum = length(GoalIds),
        IsOpened = util:get_open_day() >= StDay,
        F3 = fun(GoalId, NewSendList) ->
            case lists:keyfind(GoalId, 1, GoalList) of
                {GoalId, TmpRewardState} ->
                    %% 未到达开始时间 奖励状态为不可领状态
                    RewardState = ?IF(IsOpened, TmpRewardState, ?NOT_REWARD),
                    [{RankType, GoalId, GoalSum, RewardState}|NewSendList];
                _ ->
                    [{RankType, GoalId, GoalSum, ?NOT_REWARD}|NewSendList]
            end
        end,
        lists:foldl(F3, SendList, GoalIds)
    end,
    SendList = lists:foldl(F2, [], SortTypeL),
    lib_server_send:send_to_uid(RoleId, pt_225, 22502, [SubType,SendList]).

%% 领取目标奖励
get_goal_reward(State, RoleId, RankType, SubType, GoalId, SelValue) ->
    #rush_rank_state{goal_maps = GoalMaps} = State,
    GoalIds = data_rush_rank:get_goal_reward_ids(RankType),
    DefGoalList = [{Id, ?NOT_REWARD} || Id <- GoalIds],
    GoalList = maps:get({RankType, SubType, RoleId}, GoalMaps, DefGoalList),
    case lib_rush_rank:check([{is_opened, RankType}, {goal_reward_cfg, RankType, GoalId}]) of
        true ->
            {GoalId, RewardState} = lists:keyfind(GoalId, 1, GoalList),
            case RewardState == ?HAVE_REWARD of
                true ->
                    NewRewardState = ?FINISH,
                    NewGoalList = lists:keystore(GoalId, 1, GoalList, {GoalId, NewRewardState}),
                    NewGoalMaps = maps:put({RankType, SubType, RoleId}, NewGoalList, GoalMaps),
                    %% 存库
                    db_rush_rank_goal_save(RankType, SubType, RoleId, GoalId, NewRewardState),
                    Reward = lib_rush_rank:get_cfg_goal_reward(RankType, GoalId),
                    Produce = #produce{
                        title     = utext:get(281),
                        content   = utext:get(282),
                        reward    = Reward,
                        type      = rush_goal_reward,
                        show_tips = 1
                    },
                    lib_goods_api:send_reward_with_mail(RoleId, Produce, ?MOD_RUSH_RANK),
                    %% 日志
                    lib_log_api:log_rush_goal_reward(RoleId, RankType, GoalId, SelValue, Reward),
                    lib_server_send:send_to_uid(RoleId, pt_225, 22503, [?SUCCESS, SubType]),
                    NewState = State#rush_rank_state{goal_maps = NewGoalMaps};
                _ ->
                    lib_server_send:send_to_uid(RoleId, pt_225, 22503, [?ERRCODE(err225_goal_reward_limit), SubType]),
                    NewState = State
            end;
        {false, ErrCode} ->
            lib_server_send:send_to_uid(RoleId, pt_225, 22503, [ErrCode, SubType]),
            NewState = State
    end,
    {ok, NewState}.

%% 发送排行榜
send_rank_list(State, RankType, SubType, RoleId, SelValue1,SelValue2) ->
    #rush_rank_state{rank_maps = RankMaps} = State,
    RankList = maps:get({RankType, SubType}, RankMaps, []),
    MaxRankLen = lib_rush_rank:get_max_len(RankType),
    Limit = lib_rush_rank:get_rank_limit(RankType),
    SubRankList = lists:sublist(RankList, MaxRankLen),
    List1 = [RushRole || RushRole <- SubRankList, RushRole#rush_rank_role.value >= Limit],
    F = fun(#rush_rank_role{role_id = TmpRoleId, value = Value,value2=Value2,value3=Value3, rank = Rank}) ->
        case lib_role:get_role_show(TmpRoleId) of
            [] -> Figure = #figure{};
            #ets_role_show{figure = Figure} -> skip
        end,
        {TmpRoleId, Figure#figure.name, Value,Value2,Value3,Rank,Figure#figure.vip,Figure#figure.sup_vip}
        end,
    List = lists:map(F, List1),
    Sum = length(List),
    if
        Sum == 0 ->
            {ok, BinData} = pt_225:write(22501, [SubType,RankType, 0, SelValue1, SelValue2, 0, MaxRankLen, Limit, []]),
            lib_server_send:send_to_uid(RoleId, BinData);
        true ->
            case lists:keyfind({RankType, SubType, RoleId}, #rush_rank_role.role_key, List1) of
                #rush_rank_role{rank = RoleRank, value = LastV1,value2=LastV2} -> skip;
                _ ->
                    RoleRank = 0,
                    LastV1 = SelValue1, LastV2 = SelValue2
                    % case data_rush_rank:get_rush_rank_cfg(RankType) of
                    %     #base_rush_rank{start_day = StDay, clear_day = ClDay} ->
                    %         OpenDay = util:get_open_day(),
                    %         case OpenDay >= StDay andalso OpenDay =< ClDay of %% 活动还在启动中时显示自己的数据
                    %             true -> LastSelVal = SelValue;
                    %             _    -> LastSelVal = SelValue  %% 否则显示第一名的数据
                    %         end,
                    %         RoleRank = 0;
                    %     _ -> LastSelVal = 0, RoleRank = 0
                    % end
            end,
            {ok, BinData} = pt_225:write(22501, [SubType,RankType, RoleRank, LastV1, LastV2, Sum, MaxRankLen, Limit, List]),
            lib_server_send:send_to_uid(RoleId, BinData)
    end.

%% 活动期间每日结算
day_clear(DelaySec, State) ->
    CLists =  lib_rush_rank:get_id_by_clear_day(),
    day_clear_list(DelaySec,State,CLists).

day_clear_list(_DelaySec, State,[])->
    {ok, State};
day_clear_list(DelaySec,State,[RankId|T])->
    spawn(fun() -> util:multiserver_delay(DelaySec, lib_rush_rank_mod, send_reward, [State, RankId]) end),
    day_clear_list(DelaySec,State,T).

apply_cast(State, M, F, A) ->
    M:F(State, A).

%% 每天结算的奖励
send_reward(State, RankType) ->
    #rush_rank_state{rank_maps = RankMaps} = State,
    #base_rush_rank{name = RankTypeName} = data_rush_rank:get_rush_rank_cfg(RankType),
    SubList = lib_custom_act_util:get_subtype_list(?CUSTOM_ACT_TYPE_RUSH_RANK),
    F = fun(SubType) ->
        case maps:get({RankType, SubType}, RankMaps, []) of
            [] -> skip;
            RankList ->
                Title = ?LAN_MSG(2250001),
                % Content = make_mail_content(RankList, RankTypeName),
                do_send_reward(RankList, RankType, RankTypeName, Title, 1)
        end,
        [mod_rush_rank:send_goal_list(SubType,OnlineRole#ets_online.id) || OnlineRole <- ets:tab2list(?ETS_ONLINE) ]
        end,
    [F(SubType) || SubType <- SubList],
    ok.

do_send_reward([], _RankType, _RankTypeName, _Title, _Count) -> skip;
do_send_reward([#rush_rank_role{role_id = RoleId, rank = Rank, value = Value} | RankList], RankType, Name, Title, Count) ->
    case lib_role:get_role_show(RoleId) of
        [] ->
            ?ERR("rush rank can not find role info :~p~n", [RoleId]),
            do_send_reward(RankList, RankType, Name, Title, Count);
        #ets_role_show{figure = #figure{career = Career, name = RoleName}} ->
            case lib_rush_rank:get_rank_reward(RankType, Rank, Career) of %% 奖励根据职业有区别
                [] ->
                    ?ERR("rush rank can not find reward :~p~n", [[RankType, Rank, Career]]),
                    do_send_reward(RankList, RankType, Name, Title, Count);
                Reward ->
                    if
                        Count rem 20 == 0 -> timer:sleep(500);
                        true -> skip
                    end,
                    if
                        Rank =/= 1 -> skip;
                        true -> lib_chat:send_TV({all}, ?MOD_RUSH_RANK, 1, [RoleName, Name])
                    end,
                    Content = uio:format(?LAN_MSG(2250002), [Name,Rank]),
                    lib_mail_api:send_sys_mail([RoleId], ?MOD_RUSH_RANK, Title, Content, Reward),
                    %% 日志
                    lib_log_api:log_rush_rank_reward(RoleId, RankType, Rank, Value, Reward),
                    do_send_reward(RankList, RankType, Name, Title, Count + 1)
            end
    end;
do_send_reward([R | _RankList], RankType, _Name, _Title, _Count) ->
    ?ERR("rush rank back data:~p,~nrank_type:~p~n", [R, RankType]),
    skip.

% %% 获取邮件内容
% make_mail_content(RankList, RankTypeName) ->
%     [First, Second, Third, Fourth, Fifth] = make_mail_rolename_content(RankList, [[], [], [], [], []], 1),
%     uio:format(?LAN_MSG(2250002), [RankTypeName, First, Second, Third, Fourth, Fifth]).

% %% 获取四个排名段的玩家名字[{rank, name}]
% make_mail_rolename_content(RankList, [First, Second, Third, Fourth, Fifth], Rank) when Rank > 0, Rank =< 50 ->
%     case lists:keyfind(Rank, #rush_rank_role.rank, RankList) of
%         #rush_rank_role{role_id = RoleId} ->
%             case lib_role:get_role_show(RoleId) of
%                 #ets_role_show{figure = #figure{name = TmpRoleName}} -> RoleName = unicode:characters_to_list(TmpRoleName, unicode);
%                 _ -> RoleName = ?LAN_MSG(2250003)
%             end;
%         _ -> RoleName = ?LAN_MSG(2250004)
%     end,
%     if
%         Rank == 1 ->
%             NameList = [[{Rank, RoleName} | First], Second, Third, Fourth, Fifth];
%         Rank >= 2 andalso Rank =< 3 ->
%             NameList = [First, [{Rank, RoleName} | Second], Third, Fourth, Fifth];
%         Rank >= 4 andalso Rank =< 10 ->
%             NameList = [First, Second, [{Rank, RoleName} | Third], Fourth, Fifth];
%         Rank >= 11 andalso Rank =< 30 ->
%             NameList = [First, Second, Third, [{Rank, RoleName} | Fourth], Fifth];
%         Rank >= 31 andalso Rank =< 50 ->
%             NameList = [First, Second, Third, Fourth, [{Rank, RoleName} | Fifth]];
%         true ->
%             NameList = [First, Second, Third, Fourth, Fifth]
%     end,
%     make_mail_rolename_content(RankList, NameList, Rank + 1);
% make_mail_rolename_content(_RankList, [First, Second, Third, Fourth, Fifth], _Rank) ->
%     NewFirst = lists:keysort(1, First),
%     NewSecond = lists:keysort(1, Second),
%     NewThird = lists:keysort(1, Third),
%     NewFourth = lists:keysort(1, Fourth),
%     NewFifth = lists:keysort(1, Fifth),
%     LastFirst = [Name || {_, Name} <- NewFirst],
%     LastSecond = [Name || {_, Name} <- NewSecond],
%     LastThird = [Name || {_, Name} <- NewThird],
%     LastFourth = [Name || {_, Name} <- NewFourth],
%     LastFifth = [Name || {_, Name} <- NewFifth],
%     [util:link_list(LastFirst, "、"), util:link_list(LastSecond, "、"), util:link_list(LastThird, "、"), util:link_list(LastFourth, "、"), util:link_list(LastFifth, "、")].

%%----------------db-----------------------%%
db_rush_rank_role_select() ->
    Sql = io_lib:format(?sql_rush_rank_role_select, []),
    db:get_all(Sql).

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

db_rush_rank_role_save(RankRole) ->
    #rush_rank_role{
        rank_type = RankType,
        sub_type  = SubType,
        role_id   = RoleId,
        value     = Value,
        value2    = Value2,
        value3    = Value3,
        value4    = Value4,
        value5    = Value5,
        time      = Time
    } = RankRole,
    Sql = io_lib:format(?sql_rush_rank_role_save, [RankType, SubType, RoleId, Value, Value2, Value3,Value4,Value5, Time]),
    db:execute(Sql).

db_rush_rank_goal_save(RankType, SubType, RoleId, GoalId, State) ->
    Sql = io_lib:format(?sql_rush_rank_goal_save, [RankType, SubType, RoleId, GoalId, State]),
    db:execute(Sql).

db_rush_rank_delete_by_id(RankType, SubType, RoleId) ->
    Sql = io_lib:format(?sql_rush_rank_role_delete_by_role_id, [RankType, SubType, RoleId]),
    db:execute(Sql).

db_rush_rank_delete_by_value(RankType, SubType, Value) ->
    Sql = io_lib:format(?sql_rush_rank_role_delete_by_value, [RankType, SubType, Value]),
    db:execute(Sql).
