%%%------------------------------------
%%% @Module  :  lib_ranking_api
%%% @Author  :  xiaoxiang
%%% @Created :  2016-11-17
%%% @Description: 榜单
%%%------------------------------------

-module(lib_common_rank_api).

-export([
    login_praise/1
    ,handle_event/2
    ,timer_common_rank/0
    ,refresh_common_rank/2
    ,refresh_common_rank/3
    ,login/1
    ,logout/1
    ,is_exist/2
    ,daily_clear/0
    ]).

-export([
    refresh_rank_by_guild/1
    ,refresh_guild_labor_rank/1
    ,get_guild_title_id/0
    ,disband_guild/1
    ,rename_guild/2
    ,rechange_guild_chief/3
    ]).

-export([
    refresh_rank_by_equip/1
    ,refresh_rank_by_child/1
    ,refresh_rank_by_foster/2
    ,refresh_rank_by_fashion/1
    ,refresh_rank_by_dsgt/1
    ,refresh_rank_by_warsoul/1
    ,refresh_rank_by_dress_up/2
    ,refresh_rank_by_photo/1
    ,get_role_photo_num/1
    ]).

-export([refresh_equip_stars/1]).

-include("common_rank.hrl").
-include("server.hrl").
-include("figure.hrl").
-include("def_event.hrl").
-include("def_fun.hrl").
-include("rec_event.hrl").
-include("predefine.hrl").
-include("common.hrl").
-include("guild.hrl").
-include("def_module.hrl").
-include("role.hrl").
-include("role_foster.hrl").
-include("designation.hrl").
-include("equipment.hrl").
-include ("rec_dress_up.hrl").
-include ("profile_photo.hrl").
-include ("flower.hrl").


daily_clear() ->
    db:execute(?SQL_DELETE_COMMON_PRAISE_ROLE, []),
    ok.

login_praise(Id) ->
    case db:get_all(?SQL_SELECT_COMMON_PRAISE_ROLE, [Id]) of
        DataL = [_|_] ->
            update_praise_data(Id, DataL);
        _ ->
            []
    end.

update_praise_data(RoleId, DataL) ->
    Now = utime:unixtime(),
    NewDataL = lists:filter(fun([_RankType, _PraiseId, Time]) -> 
        utime:is_same_day(Time, Now)
    end, DataL),
    DbDelete = DataL -- NewDataL,
    DbDelete =/= [] andalso [db:execute(?SQL_BTACH_DELETE_COMMON_PRAISE_ROLE, [RoleId, RankTypeX]) || [RankTypeX, _, _] <- DbDelete ],
    [{RankTypeX1, PraiseIdX, TimeX} || [RankTypeX1, PraiseIdX, TimeX] <- NewDataL].

%% 等级排行榜
handle_event(Player, #event_callback{type_id = ?EVENT_LV_UP}) when is_record(Player, player_status) ->
    #player_status{figure = #figure{career = Career}} = Player,
    RankTypeL = lib_common_rank:get_rank_type_by_career(Career, ?RANK_TYPE_LV),
    refresh_common_rank(Player, RankTypeL),
    {ok, Player};

%% 战力排行榜
handle_event(Player, #event_callback{type_id = ?EVENT_COMBAT_POWER}) when is_record(Player, player_status) ->
    #player_status{figure = #figure{career = Career}} = Player,
    RankTypeL = lib_common_rank:get_rank_type_by_career(Career, ?RANK_TYPE_COMBAT),
    refresh_common_rank(Player, RankTypeL),
    {ok, Player};

handle_event(Player, #event_callback{type_id = ?EVENT_ONLINE_FLAG, data = OnlineFlag}) when is_record(Player, player_status) ->
    #player_status{id = RoleId, online = OldOnlineFlag} = Player,
    NowTime = utime:unixtime(),
    if
        OnlineFlag == ?ONLINE_ON ->
            mod_common_rank:change_online_flag(RoleId,?ONLINE_ON,NowTime);
        OldOnlineFlag == ?ONLINE_ON andalso OnlineFlag == ?ONLINE_OFF ->
            mod_common_rank:change_online_flag(RoleId,?ONLINE_OFF,NowTime);
        true -> skip
    end,
    {ok, Player};

handle_event(Player, _Ec) ->
    ?ERR("unkown event_callback:~p", [_Ec]),
    {ok, Player}.


%% --------------------------------------------------------------------------
%% 社团排行榜
refresh_rank_by_guild(Guild) when is_record(Guild, guild) ->
    refresh_common_rank(Guild, ?RANK_TYPE_GUILD).

%% 社团活跃排行榜
refresh_guild_labor_rank(Guild) when is_record(Guild, guild) ->
    refresh_common_rank(Guild, ?RANK_TYPE_GUILD_LABOR).

%% 获取公会排行第一的 称号
get_guild_title_id() ->
    lib_common_rank:get_title_id(?RANK_TYPE_GUILD).

%% 解散公会
disband_guild(GuildId) ->
    mod_common_rank:disband_guild(GuildId, [?RANK_TYPE_GUILD,?RANK_TYPE_GUILD_LABOR,?RANK_TYPE_GUILD_LABOR_LAST]).

%% 改名公会
rename_guild(GuildId, Name) ->
    mod_common_rank:rename_guild(GuildId, Name, [?RANK_TYPE_GUILD,?RANK_TYPE_GUILD_LABOR,?RANK_TYPE_GUILD_LABOR_LAST]).

%%团长变更
rechange_guild_chief(GuildId, RoleId, Name)->
    mod_common_rank:rechange_guild_chief(GuildId, RoleId, Name, [?RANK_TYPE_GUILD,?RANK_TYPE_GUILD_LABOR,?RANK_TYPE_GUILD_LABOR_LAST]).


%% 同步公会榜单
% sync_guild_rank() ->
%     mod_common_rank:sync_guild_rank().

%% 宝宝
refresh_rank_by_child(Player) ->
    refresh_common_rank(Player, ?RANK_TYPE_BABY).

%% 装备
refresh_rank_by_equip(Player) ->
    #player_status{figure = #figure{career = Career}} = Player,
    RankTypeL = lib_common_rank:get_rank_type_by_career(Career, ?RANK_TYPE_EQUIP),
    refresh_common_rank(Player, RankTypeL).

refresh_equip_stars(Player) ->
    update_common_rank_data(Player, ?RANK_TYPE_EQUIP, second_value).

%% 进阶系统
refresh_rank_by_foster(Player, Cells) ->
    lists:map(fun(Cell) ->
        RankType = lib_common_rank:get_rank_type_by_foster_cell(Cell),
        refresh_common_rank(Player, RankType)
     end, Cells).

refresh_rank_by_fashion(Player) ->
    refresh_common_rank(Player, ?RANK_TYPE_FASHION).

refresh_rank_by_dsgt(Player) ->
    refresh_common_rank(Player, ?RANK_TYPE_DESIGNATION).

refresh_rank_by_warsoul(Player) ->
    refresh_common_rank(Player, ?RANK_TYPE_WARSOUL).

refresh_rank_by_dress_up(Player, SumNum) ->
    PhotoNum = get_role_photo_num(Player),
    refresh_common_rank(Player, ?RANK_TYPE_DRESS, [SumNum+PhotoNum]).

refresh_rank_by_photo(Player) ->
    #player_status{figure = Figure, dress_up = StatusDressUp} = Player,
    #status_dress_up{enabled_map = EnabledMap} = StatusDressUp,
    {ColorList, _NotOpenNum} = lib_dress_up:calc_all_dress_up(Figure#figure.lv, 1, EnabledMap),
    {ColorList1, _NotOpenNum1} = lib_dress_up:calc_all_dress_up(Figure#figure.lv, 2, EnabledMap),
    F = fun({_, Num}, TSumNum) ->
        Num + TSumNum
        end,
    SumNum = lists:foldl(F, 0, ColorList ++ ColorList1),
    PhotoNum = get_role_photo_num(Player),
    SumNum1 = SumNum + PhotoNum,
    refresh_common_rank(Player, ?RANK_TYPE_DRESS, [SumNum1]).


get_role_photo_num(Player) ->
    #player_status{profile_photo_info = PhotoInfo, figure = Figure} = Player,
    #profile_photo_info{photo_list = PhotoList} = PhotoInfo,
    #figure{career = Career} = Figure,
    TransformId = transform:get_transform_id(Player),
    F = fun(TTransformId, TList) ->
        case data_transform:get_career_transform_image(Career, TTransformId) of
            PhotoId when is_integer(PhotoId) ->
                case lists:member(PhotoId, TList) of
                    true -> TList;
                    _ -> [PhotoId|TList]
                end;
            _ -> TList
        end end,
    AllPhotoList = lists:foldl(F, PhotoList, lists:seq(0, TransformId)),
    length(AllPhotoList).

%% 每5分钟排次序
timer_common_rank() ->
    [ mod_common_rank:timer_common_rank(Type) || Type <- ?RANK_TYPE_LIST ].

login(Player) ->
    refresh_common_rank_by_all(Player),
    ok.

logout(_Player) ->
    ok.

%% 刷新榜单,最好在里面统一处理,修改方便
refresh_common_rank(Guild, RankType) when is_record(Guild, guild) ->
    lib_common_rank:refresh_common_rank(RankType, Guild);

refresh_common_rank(PlayInfo, RankType) when is_record(PlayInfo, player_status) ->
    #player_status{figure = #figure{lv = Lv}} = PlayInfo,
    case Lv >= lib_module:get_open_lv(?MOD_RANK, 1) of
        true ->
            lib_common_rank:refresh_common_rank(RankType, PlayInfo);
        _ -> skip
    end,
    ok;

refresh_common_rank(RoleId, RankType) when is_integer(RoleId) ->
    Lv = case lib_role:get_role_show(RoleId) of
         [] -> 999;
         #ets_role_show{figure = TmpFigure} -> TmpFigure#figure.lv
    end,
    case Lv >= lib_module:get_open_lv(?MOD_RANK, 1) of
        true -> lib_player:apply_cast(RoleId, ?MODULE, refresh_common_rank, [RankType]);
        _ -> skip
    end.

refresh_common_rank(PlayInfo, RankType, Args) when is_record(PlayInfo, player_status) ->
    #player_status{figure = #figure{lv = Lv}} = PlayInfo,
    case Lv >= lib_module:get_open_lv(?MOD_RANK, 1) of
        true -> lib_common_rank:refresh_common_rank_with_args(RankType, PlayInfo, Args);
        _    -> skip
    end,
    ok;

refresh_common_rank(PlayInfo, RankType, Args) when is_integer(PlayInfo) ->
    Lv = case lib_role:get_role_show(PlayInfo) of
        [] -> 999;
        #ets_role_show{figure = TmpFigure} -> TmpFigure#figure.lv
    end,
    case Lv >= lib_module:get_open_lv(?MOD_RANK, 1) of
        true -> lib_player:apply_cast(PlayInfo, ?MODULE, refresh_common_rank, [RankType, Args]);
        _    -> skip
    end.

%% 刷新榜单数据
refresh_common_rank_by_all(Player) ->
    #player_status{id = RoleId, flower = #flower{fame = Fame, charm = Charm}} = Player,
    F = fun(RankType) when RankType =/= ?RANK_TYPE_CHARM_WEEK andalso RankType =/= ?RANK_TYPE_GENEROURS ->
            case lists:member(RankType, ?RANK_TYPE_ECL) of
                true ->
                    RankTypeL = lib_common_rank:get_rank_type_by_career(Player#player_status.figure#figure.career, RankType),
                    [refresh_common_rank(Player, RankX) || RankX <- RankTypeL];
                _ ->
                    IsCareerRankType = lists:member(RankType, ?RANK_TYPE_CAREER),
                    if IsCareerRankType ->
                            skip;
                        true ->
                            refresh_common_rank(Player, RankType)
                    end
            end;
        (_RankType)->
            Value = if _RankType == ?RANK_TYPE_CHARM_WEEK -> Charm;
                true -> Fame
            end,
            mod_common_rank:refresh_common_rank(_RankType, {RoleId, Value})
        end,
    lists:map(F, ?RANK_TYPE_LIST).

%% 非排行值但需更新显示的值
update_common_rank_data(Player, RankType, RecTag) ->
    case check([{rank_type, RankType}, {rec_field_check, RecTag}]) of
        true ->
            #player_status{id = RoleId, equipment = #equipment{stars = Star}} = Player,
            IsEquip = lists:member(RankType, ?RANK_TYPE_ALL_EQUIPS),
            UpdateData =
            if IsEquip ->
                    Star;
                true ->
                    undefined
            end,
            case UpdateData of
                undefined ->
                    skip;
                _A ->
                    mod_common_rank:update_common_rank_data(RoleId, RankType, [{RecTag, UpdateData}]),
                    ok
            end;
        _ ->
            skip
    end.


is_exist(_I, []) -> false;
is_exist(I, [H | T]) ->
    case I == H of
        true ->
            true;
        false ->
            is_exist(I, T)
    end.


check([]) ->
    true;
check([{rec_field_check, RecTag}|Rest]) ->
    Fields = record_info(fields, common_rank_role),
    case ulists:index_of(RecTag, Fields) of
        0 ->
            false;
        _A ->
            if RecTag =/= value ->
                    check(Rest);
                true ->
                    false
            end
    end;
check([{rank_type, RankType}|Rest]) ->
    case lists:member(RankType, ?RANK_TYPE_LIST) of
        true ->
            check(Rest);
        _ ->
            false
    end;
check(_) ->
    false.