%%%------------------------------------
%%% @Module  : mod_common_rank
%%% @Author  :  xiaoxiang
%%% @Created :  2016-11-17
%%% @Description: 通用榜单
%%%------------------------------------
-module(mod_common_rank).

-include("common_rank.hrl").
-include("common.hrl").

-export([
         refresh_common_rank_by_list/1
        , refresh_common_rank/2
        , send_rank_list/6
        , timer_common_rank/1
        , rename_guild/3
        , rechange_guild_chief/4
        , get_top_rank/4
        ,local_rank_upload/1
        ]).

-export([start_link/0]).
-export([init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3]).

-compile(export_all).

get_fashion_rank_top_role(Num) ->
    RankType = ?RANK_TYPE_FASHION,
    get_rank_top_role(RankType, Num).

get_rank_top_role(RankType, Num) ->
    gen_server:call(?MODULE, {get_rank_top_role, RankType, Num}).
%% @param [{RankType, CommonRankRole}]
refresh_common_rank_by_list(List) ->
    gen_server:cast(?MODULE, {'refresh_common_rank_by_list', List}).

%% 根据类型刷新榜单
refresh_common_rank(RankType, CommonRankRole) ->
    gen_server:cast(?MODULE, {'refresh_common_rank', RankType, CommonRankRole}).

%% 发送榜单的数据
send_rank_list(RankType, Start, Len, RoleId, SelValue, SelSecValue) ->
    gen_server:cast(?MODULE, {'send_rank_list', RankType, Start, Len, RoleId, SelValue, SelSecValue}).

%% 定时刷新排行榜
timer_common_rank(RankType) ->
    gen_server:cast(?MODULE, {'timer_common_rank', RankType}).

%% 解散公会
disband_guild(GuildId, RankTypeList) ->
    gen_server:cast(?MODULE, {'disband_guild', GuildId, RankTypeList}).

%% 公会改名
rename_guild(GuildId, Name, RankTypeList) ->
    gen_server:cast(?MODULE, {'rename_guild', GuildId, Name, RankTypeList}).

%%团长改变
rechange_guild_chief(GuildId,ChiefID,Name, RankTypeList)->
    gen_server:cast(?MODULE, {'rechange_guild_chief', GuildId,ChiefID,Name, RankTypeList}).

%% 点赞别人
rank_praise(RoleId, OtRoleId, RankType) ->
    gen_server:cast(?MODULE, {'rank_praise', RoleId, OtRoleId, RankType}).

%% 获取前N名排名
get_top_rank(RankType, Start, Len, Sid) ->
    gen_server:cast(?MODULE, {'get_top_rank', RankType, Start, Len, Sid}).

%% 获取首度目标达成数据信息
get_first_top_info(Sid, RankType, RewardedTarget) ->
    gen_server:cast(?MODULE, {'get_first_top_info', Sid, RankType, RewardedTarget}).

get_first_top_reward(RoleId, RankType, Target) ->
    gen_server:cast(?MODULE, {'get_first_top_reward', RoleId, RankType, Target}).

get_top_rank_list(Sid, RankType) ->
    gen_server:cast(?MODULE, {'get_top_rank_list', Sid, RankType}).

apply_cast(M, F, A) ->
    gen_server:cast(?MODULE, {'apply_cast', M, F, A}).

%% 每天结算
day_clear(DelaySec) ->
    RandTime = urand:rand(1, 1000),
    spawn(fun() -> timer:sleep(RandTime), gen_server:cast(?MODULE, {'day_clear', DelaySec}) end).

daily_timer(Type)->
    RandTime = urand:rand(1, 1000),
    spawn(fun() -> timer:sleep(RandTime), gen_server:cast(?MODULE, {'daily_timer', Type}) end).

timer_update()->
    RandTime = urand:rand(100, 1500),
    spawn(fun() -> timer:sleep(RandTime), gen_server:cast(?MODULE, {'timer_update'}) end).


%%  根据榜单类型转移榜单里玩家位置
change_rank_by_type(RoleId, OldType, RankType) ->
    gen_server:cast(?MODULE, {'change_rank_by_type', RoleId, OldType, RankType}).

change_online_flag(RoleID,OnLine,OffTime) ->
    gen_server:cast(?MODULE, {'change_online_flag', RoleID,OnLine,OffTime}).

choose_runer()->
    gen_server:cast(?MODULE,{'choose_runer'}).

%% 更新个人部分数据
update_common_rank_data(RoleId, RankType, UpdateList) ->
    gen_server:cast(?MODULE, {'update_common_rank_data', RoleId, RankType, UpdateList}).

%% 同步榜单数据到跨服榜
gm_sync_to_kf_rank() ->
    gen_server:cast(?MODULE, {'gm_sync_to_kf_rank'}).

%% 修复装备榜数据
gm_repair_equip_rank() ->
    gen_server:cast(?MODULE, {'gm_repair_equip_rank'}).

get_labor_rank(GuildID,Target)->
    gen_server:call(?MODULE, {get_labor_rank,GuildID,Target}).

%% 获取等级、战力榜前十
send_top_rank_info() ->
    gen_server:cast(?MODULE, {'send_top_rank_info'}).

%% 获取战力榜前三十
send_top_30_combat_rank(RolePid) ->
    gen_server:cast(?MODULE, {'send_top_30_combat_rank', RolePid}).

%% 本地等级/战力榜上传
local_rank_upload(RankTypeList) ->
    gen_server:cast(?MODULE, {local_rank_upload, RankTypeList}).

%% ---------------------------------------------------------------------------
start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

%% ---------------------------------------------------------------------------
init([]) ->
    % State = common_rank_logic:init(),
    self() ! {'rank_init'},
    {ok, #common_rank_state{}}.

%% ---------------------------------------------------------------------------
%% handle_call({'reload'}, _From, _State) ->
%%     State = common_rank_logic:init(),
%%     {reply, ok, State};
%% handle_call({'state'}, _From, State) ->
%%     % ?ERR1("~p state:~p~n", [?MODULE, State]),
%%     {reply, State, State};
handle_call({get_labor_rank,GuildID,Target},_From,State)->
    Reply = common_rank_logic:get_labor_rank(State, GuildID,Target),
    {reply, Reply, State};
handle_call({get_rank_top_role, RankType, Num}, _From, State) ->
    Reply = common_rank_logic:get_rank_top_role(State, RankType, Num),
    {reply, Reply, State};
handle_call(_Request, _From, State) ->
    %% ?ERR1("Handle unkown request[~w]~n", [_Request]),
    Reply = ok,
    {reply, Reply, State}.

%% ---------------------------------------------------------------------------
handle_cast(Msg, State) ->
    case catch do_handle_cast(Msg, State) of
        {ok, NewState} ->
            {noreply, NewState};
        Err ->
            %% util:errlog("~p ~p Msg:~p Cast_Error:~p ~n", [?MODULE, ?LINE, Msg, Err]),
            ?ERR("Msg:~p Cast_Error:~p~n", [Msg, Err]),
            {noreply, State}
    end.

do_handle_cast({'refresh_common_rank_by_list', List}, State) ->
    common_rank_logic:refresh_common_rank_by_list(State, List);
do_handle_cast({'refresh_common_rank', RankType, CommonRankRole}, State) ->
    common_rank_logic:refresh_common_rank(State, RankType, CommonRankRole);
do_handle_cast({'send_rank_list', RankType, Start, Len, RoleId, SelValue, SelSecValue}, State) ->
    common_rank_logic:send_rank_list(State, RankType, Start, Len, RoleId, SelValue, SelSecValue),
    {ok, State};
do_handle_cast({'timer_common_rank', RankType}, State) ->
    common_rank_logic:timer_common_rank(RankType, State);

do_handle_cast({'disband_guild', GuildId, RankTypeList}, State) ->
    common_rank_logic:disband_guild(State, GuildId, RankTypeList);

do_handle_cast({'rename_guild', GuildId, Name, RankTypeList}, State) ->
    common_rank_logic:rename_guild(State, GuildId, Name, RankTypeList);

do_handle_cast({'rechange_guild_chief', GuildId,ChiefID,Name, RankTypeList}, State) ->
    common_rank_logic:rechange_guild_chief(State, GuildId,ChiefID,Name, RankTypeList);

do_handle_cast({'rank_praise', RoleId, OtRoleId, RankType}, State) ->
    common_rank_logic:rank_praise(State, RoleId, OtRoleId, RankType);

do_handle_cast({'apply_cast', M, F, A}, State) ->
    common_rank_logic:apply_cast(State, M, F, A);

do_handle_cast({'day_clear', DelaySec}, State) ->
    common_rank_logic:day_clear(DelaySec, State);

do_handle_cast({'daily_timer',Type}, State) ->
    common_rank_logic:daily_timer(Type, State);

do_handle_cast({'timer_update'},State)->
    common_rank_logic:timer_update(State);

do_handle_cast({'gm_daily_timer'}, State) ->
    common_rank_logic:gm_daily_timer(State);

do_handle_cast({'change_rank_by_type', RoleId, OldType, RankType}, State) ->
    common_rank_logic:change_rank_by_type(State, RoleId, OldType, RankType);

do_handle_cast({'change_online_flag',  RoleID,OnLine,OffTime}, State) ->
    common_rank_logic:change_online_flag(State, RoleID,OnLine,OffTime);

do_handle_cast({'choose_runer'},State)->
    mod_glamour_mgr:choose_runer(State);

do_handle_cast({'get_top_rank', RankType, Start, Len, Sid}, State) ->
    common_rank_logic:get_top_rank(RankType, Start, Len, State, Sid);

do_handle_cast({'gm_repair_equip_rank'}, State) ->
    common_rank_logic:gm_repair_equip_rank(State);

do_handle_cast({'update_common_rank_data', RoleId, RankType, UpdateList}, State) ->
    common_rank_logic:update_common_rank_data(RoleId, RankType, UpdateList, State);

do_handle_cast({'get_first_top_info', Sid, RankType, RewardedTarget}, State) ->
    common_rank_logic:get_first_top_info(Sid, RankType, RewardedTarget, State);

do_handle_cast({'get_first_top_reward', RoleId, RankType, Target}, State) ->
    common_rank_logic:get_first_top_reward(RoleId, RankType, Target, State);

do_handle_cast({local_rank_upload, RankTypeList}, State) ->
    common_rank_logic:local_rank_upload(RankTypeList, State);

do_handle_cast({'get_top_rank_list', Sid, RankType}, State) ->
    common_rank_logic:get_top_rank_list(Sid, RankType, State);

do_handle_cast({'send_top_rank_info'}, State) ->
    common_rank_logic:send_top_rank_info(State);

do_handle_cast({'send_top_30_combat_rank', RolePid}, State) ->
    common_rank_logic:send_top_30_combat_rank(RolePid, State);

do_handle_cast(_Msg, State) ->
    %% ?ERR1("Handle unkown msg[~w]~n", [_Msg]),
    {ok, State}.

%% ---------------------------------------------------------------------------

handle_info(Info, State) ->
    case catch do_handle_info(Info, State) of
        {ok, NewState} ->
            {noreply, NewState};
        _Err ->
            ?ERR("Handle unkown info[~w]~n", [Info]),
            {noreply, State}
    end.

do_handle_info({'refresh_average_lv'}, State) ->
    common_rank_logic:refresh_average_lv(State);

do_handle_info({'rank_init'}, _State) ->
    NewState = common_rank_logic:init(),
    Ref = erlang:send_after(?RANK_INTERVAL, self(), {'timer_refresh_common_rank'}),
    DsgtRefresh = get_dsgt_refresh_time(),
    erlang:send_after(DsgtRefresh, self(), {'dsgt_refresh_common_rank'}),
    {ok, NewState#common_rank_state{timer = Ref}};

do_handle_info({'timer_refresh_common_rank'}, State) ->
    #common_rank_state{timer = OldRef} = State,
    % BefMemory = erlang:process_info(self(), memory),
    % BefHeap   = erlang:process_info(self(), heap_size),
    NewState = common_rank_logic:timer_refresh_common_rank_logic(?RANK_TYPE_LIST, State),
    % AftMemory = erlang:process_info(self(), memory),
    % AftHeap   = erlang:process_info(self(), heap_size),
    % ?ERR("before ~p ~p after ~p ~p", [BefMemory, BefHeap, AftMemory, AftHeap]),
    NewRef = util:send_after(OldRef, ?RANK_INTERVAL, self(), {'timer_refresh_common_rank'}),
    {ok, NewState#common_rank_state{timer = NewRef}};

do_handle_info({'dsgt_refresh_common_rank'}, State) ->
    NewState = common_rank_logic:interval_refresh_dsgt_rank(State),
    DsgtRefresh = get_dsgt_refresh_time(),
    erlang:send_after(DsgtRefresh, self(), {'dsgt_refresh_common_rank'}),
    {ok, NewState};

do_handle_info(_Info, State) ->
    {ok, State}.

%% ---------------------------------------------------------------------------
terminate(_Reason, _State) ->
    ok.

%% ---------------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
    {ok, State}.


get_dsgt_refresh_time() ->
    Sec = data_ranking:get_value(refresh_time),
    Sec*1000.