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

-module(lib_common_rank).

-export([
    refresh_common_rank/2
    ,refresh_common_rank_with_args/3
    ,get_rank_type_by_career/2
    ,get_rank_type_by_foster_cell/1
    ,get_rank_config/1
    ,get_title_id/1
    ,get_title_id/2
    ,get_title_name/1
    ,get_rank_type_name/1
    ,get_id_name/1
    ,get_foster_cell_grade/2
    ,get_foster_cell_power/2
    ,get_foster_cell_lv/2
    ,get_sub_foster_cell_power/2
    ,get_foster_cell_by_rank_type/1
    ,get_role_warsoul_info/2

    ,db_get_role_first_top_reward/1

    ,role_rank_praise_update/3
    ]).

-include("server.hrl").
-include("common_rank.hrl").
-include("figure.hrl").
-include("flower.hrl").
-include("guild.hrl").
-include("common.hrl").
-include("designation.hrl").
-include("role.hrl").
-include("predefine.hrl").
-include("def_fun.hrl").
-include("dungeon.hrl").
-include("goods.hrl").
-include("equipment.hrl").
-include("role_foster.hrl").
-include("fashion.hrl").
-include("child.hrl").
-include ("warsoul.hrl").
-include ("def_goods.hrl").
-include ("rec_offline.hrl").
-include ("rec_dress_up.hrl").
-include ("profile_photo.hrl").

role_rank_praise_update(Player, RankType, OtRoleId) ->
    #player_status{id = RoleId, role_rank_praise = RoleRankPraise} = Player,
    case lists:keyfind(RankType, 1, RoleRankPraise) of
        {_, _, _} ->
            ok;
        _ ->
            Time = utime:unixtime(),
            db:execute(?SQL_REPLACE_COMMON_PRAISE_ROLE, [RoleId, RankType, OtRoleId, Time]),
            NewRoleRankPraise = lists:keystore(RankType, 1, RoleRankPraise, {RankType, OtRoleId, Time}),
            NewPlayer = Player#player_status{role_rank_praise = NewRoleRankPraise},
            {ok, NewPlayer}
    end.

%% record基础数据
make_record([RankType, Guild|_]) when is_record(Guild, guild)->
    #guild{
        id           = GuildId,
        name         = GuildName,
        chief_id     = ChairmanId,
        chief_name   = ChairmanName,
        lv           = Lv,
        member_num   = MembersNum,
        combat_power = Combat,
        week_labor   = WLabor,
        week_labor_last = WLaborL,
        flag = Flag,
        add_member_num = AddNum
    } = Guild,
    %?PRINT("~p~n", [Value]),
    Value =
    if
        RankType == ?RANK_TYPE_GUILD_LABOR  ->
            case utime:logic_day_of_week()<5 of
                true->
                    WLabor;
                _->
                    max(WLabor-WLaborL,0)
            end;
        RankType == ?RANK_TYPE_GUILD_LABOR_LAST ->
            WLaborL;
        RankType == ?RANK_TYPE_GUILD->
            Combat;
        true ->
            0
    end,
    SecValue =
    if
        RankType == ?RANK_TYPE_GUILD_LABOR  ->
            Combat;
        RankType == ?RANK_TYPE_GUILD_LABOR_LAST ->
            Combat;
        true ->
            0
    end,
    #common_rank_guild{
        guild_key     = {RankType, GuildId},
        rank_type     = RankType,
        guild_id      = GuildId,
        guild_name    = GuildName,
        flag          = Flag,
        chairman_id   = ChairmanId,
        chairman_name = ChairmanName,
        lv            = Lv,
        members_num   = MembersNum,
        add_mem_num   = AddNum,
        value         = Value,
        second_value  = SecValue,
        time          = utime:unixtime()
    };
%% record基础数据
make_record([RankType, Player, Args|_]) when is_record(Player, player_status) ->
    %% ?PRINT("~p~n", [RankType]),
    #player_status{id = Id, figure = #figure{lv = Lv}, combat_power = Combat, equipment = Equipment,
     status_child = #status_child{child_name = ChildName, child_power = ChildPower, extra_power = ChildPower1},
     role_fashion = #role_fashion{power1 = FashionPower},
     dsgt_status = #dsgt_status{power = DsgtPower},
     role_war_soul = #role_war_soul{total_power = WarSoulPower},
     dress_up = #status_dress_up{enabled_map = EnabledMap, power = DressUpPower}
    } = Player,
    IsPower = lists:member(RankType, ?RANK_TYPE_ALL_COMBATS),
    IsLv    = lists:member(RankType, ?RANK_TYPE_ALL_LVS),
    IsEquip = lists:member(RankType, ?RANK_TYPE_ALL_EQUIPS),
    IsFoster = lists:member(RankType, ?RANK_TYPE_FOSTER),
    IsFoster1 = lists:member(RankType, ?RANK_TYPE_FOSTER_1),
    IsFoster2 = lists:member(RankType, ?RANK_TYPE_FOSTER_2),
    Value =
    if IsPower ->
            Combat;
        IsLv ->
            Lv;
        IsEquip ->
            #equipment{total_power = Power} = Equipment,
            Power;
        IsFoster1 -> %% 进阶阶数
            get_foster_cell_grade(RankType, Player);
        IsFoster2 -> %% AI娘等级
            get_foster_cell_lv(RankType, Player);
        RankType == ?RANK_TYPE_FASHION ->
            lib_fashion:get_fashion_active_num(Player);
        RankType == ?RANK_TYPE_DESIGNATION ->
            lib_designation:get_all_actived_dsgt(Player);
        RankType == ?RANK_TYPE_BABY ->
            round(ChildPower+ChildPower1);
        RankType == ?RANK_TYPE_WARSOUL ->
            WarSoulPower;
        RankType == ?RANK_TYPE_FOSTERS orelse RankType == ?RANK_TYPE_AIGIRLS ->
            {SubFosterPower, _} = get_sub_foster_cell_power(RankType, Player),
            SubFosterPower;
        RankType == ?RANK_TYPE_DRESS ->
            case Args of
                [SumNum|_] -> SumNum;
                _ ->
                    {ColorList, _}  = lib_dress_up:calc_all_dress_up(Lv, 1, EnabledMap),
                    {ColorList1, _} = lib_dress_up:calc_all_dress_up(Lv, 2, EnabledMap),
                    F = fun({_, Num}, TSumNum) ->
                        Num + TSumNum
                        end,
                    SumNum = lists:foldl(F, 0, ColorList ++ ColorList1),
                    PhotoNum = lib_common_rank_api:get_role_photo_num(Player),
                    SumNum1 = SumNum + PhotoNum,
                    SumNum1
            end;
        true ->
            0
    end,
    SecValue =
        if
            RankType == ?RANK_TYPE_FASHION  ->
                FashionPower;
            RankType == ?RANK_TYPE_DESIGNATION ->
                DsgtPower;
            RankType == ?RANK_TYPE_DRESS ->
                DressUpPower;
            IsEquip ->
                Player#player_status.equipment#equipment.stars;
            IsFoster -> %% 星级
                get_foster_cell_star(RankType, Player);
            true ->
                0
        end,
    ThirdValue =
        if
            IsFoster -> %% 战力
                get_foster_cell_power(RankType, Player);
            true ->
                0
        end,
    ExtraValue =
        if RankType == ?RANK_TYPE_BABY ->
                ChildName;
            RankType == ?RANK_TYPE_FOSTERS
             orelse RankType == ?RANK_TYPE_AIGIRLS ->
                {_, SubFosterCellGrades} = get_sub_foster_cell_power(RankType, Player),
                SubFosterCellGrades;
            true ->
                ""
        end,
    #common_rank_role{
        role_key     = {RankType, Id},
        rank_type    = RankType,
        role_id      = Id,
        value        = Value,
        second_value = SecValue,
        third_value  = ThirdValue,
        extra_value  = ExtraValue,
        time         = utime:unixtime()
    }.

%% 榜单
refresh_common_rank(RankType, Info) ->
    case is_list(RankType) of
        true -> RankTypeList = RankType;
        false -> RankTypeList = [RankType]
    end,
    refresh_common_rank_by_rank_type_list(RankTypeList, Info, []),
    ok.

refresh_common_rank_with_args(RankType, Player, Args) ->
    case is_list(RankType) of
        true -> RankTypeList = RankType;
        false -> RankTypeList = [RankType]
    end,
    refresh_common_rank_by_rank_type_list(RankTypeList, Player, Args),
    ok.

refresh_common_rank_by_rank_type_list(RankTypeList, Info, Args) ->
    F = fun(RankType) -> get_refresh_list_by_rank_type(RankType, Info, Args) end,
    DeepList = lists:map(F, RankTypeList),
    List = lists:flatten(DeepList),
    case List == [] of
        true -> skip;
        false -> mod_common_rank:refresh_common_rank_by_list(List)
    end,
    ok.

%% 获得可以刷新的榜单列表
get_refresh_list_by_rank_type(RankType, Info, Args) ->
    case check(RankType, Info) of
        true ->
            CommonRank = get_common_rank(RankType, Info, Args),
            case CommonRank of
                #common_rank_role{value = Value} -> ok;
                #common_rank_guild{value = Value} -> ok;
                _ -> Value = 0
            end,
            case check_rank_value_limit(RankType, Value) of
                true ->
                    [{RankType, CommonRank}];
                _ ->
                    []
            end;
        false ->
            []
    end.

%% 过滤可以上榜的条件
check(RankType, _Player) ->
    case data_ranking:get_rank_config(RankType) of
        #rank_config{} -> true;
        _ -> false
    end.

check_rank_value_limit(RankType, Value) ->
    #rank_config{rank_limit = RankValueLimit} = data_ranking:get_rank_config(RankType),
    Value >= RankValueLimit.

%% 组装玩家的数据
get_common_rank(RankType, Info, Args) ->
    CommonRank = make_record([RankType, Info, Args]),
    CommonRank.

get_rank_type_by_career(Career, ?RANK_TYPE_LV) ->
    if Career == 1 ->
            [?RANK_TYPE_LV, ?RANK_TYPE_LV_1];
        Career == 2 ->
            [?RANK_TYPE_LV, ?RANK_TYPE_LV_2];
        Career == 3 ->
            [?RANK_TYPE_LV, ?RANK_TYPE_LV_3];
        Career == 4 ->
            [?RANK_TYPE_LV, ?RANK_TYPE_LV_4];
        true ->
            [?RANK_TYPE_LV]
    end;
get_rank_type_by_career(Career, ?RANK_TYPE_COMBAT) ->
    if Career == 1 ->
            [?RANK_TYPE_COMBAT, ?RANK_TYPE_COMBAT_1];
        Career == 2 ->
            [?RANK_TYPE_COMBAT, ?RANK_TYPE_COMBAT_2];
        Career == 3 ->
            [?RANK_TYPE_COMBAT, ?RANK_TYPE_COMBAT_3];
        Career == 4 ->
            [?RANK_TYPE_COMBAT, ?RANK_TYPE_COMBAT_4];
        true ->
            [?RANK_TYPE_COMBAT]
    end;
get_rank_type_by_career(Career, ?RANK_TYPE_EQUIP) ->
    if Career == 1 ->
            [?RANK_TYPE_EQUIP, ?RANK_TYPE_EQUIP_1];
        Career == 2 ->
            [?RANK_TYPE_EQUIP, ?RANK_TYPE_EQUIP_2];
        Career == 3 ->
            [?RANK_TYPE_EQUIP, ?RANK_TYPE_EQUIP_3];
        Career == 4 ->
            [?RANK_TYPE_EQUIP, ?RANK_TYPE_EQUIP_4];
        true ->
            [?RANK_TYPE_EQUIP]
    end;
get_rank_type_by_career(_, _) ->
    [].

get_foster_cell_power(RankType, Player) ->
    Cell = get_foster_cell_by_rank_type(RankType),
    #player_status{role_foster = RoleFoster, role_foster_skin = RoleFosterSkin} = Player,
    #role_foster{fosters = Fosters} = RoleFoster,
    #role_foster_skin{fosters = FosterSkins} = RoleFosterSkin,
    case lists:keyfind(Cell, #cell_foster.type, Fosters) of
        #cell_foster{combat = Combat1} -> Combat1;
        _ -> Combat1 = 0
    end,
    case lists:keyfind(Cell, #cell_foster_skin.type, FosterSkins) of
        #cell_foster_skin{combat = Combat2} ->
            Combat1 + Combat2;
        _ -> Combat1
    end.

get_foster_cell_grade(RankType, Player) ->
    Cell = get_foster_cell_by_rank_type(RankType),
    #player_status{role_foster = RoleFoster} = Player,
    #role_foster{fosters = Fosters} = RoleFoster,
    case lists:keyfind(Cell, #cell_foster.type, Fosters) of
        #cell_foster{grade = Grade} -> Grade;
        _A -> 0
    end.

get_foster_cell_star(RankType, Player) ->
    Cell = get_foster_cell_by_rank_type(RankType),
    #player_status{role_foster = RoleFoster} = Player,
    #role_foster{fosters = Fosters} = RoleFoster,
    case lists:keyfind(Cell, #cell_foster.type, Fosters) of
        #cell_foster{star = Star} -> Star;
        _ -> 0
    end.

get_foster_cell_lv(RankType, Player) ->
    Cell = get_foster_cell_by_rank_type(RankType),
    #player_status{role_foster = RoleFoster} = Player,
    #role_foster{fosters = Fosters} = RoleFoster,
    case lists:keyfind(Cell, #cell_foster.type, Fosters) of
        #cell_foster{lv = CellLv} -> CellLv;
        _A -> 0
    end.

get_foster_cell_by_rank_type(RankType) ->
    case RankType of
        ?RANK_TYPE_FHORSE -> ?FHORSE;
        ?RANK_TYPE_FWING -> ?FWING;
        ?RANK_TYPE_FPEARL -> ?FPEARL;
        ?RANK_TYPE_FWEAPON -> ?FWEAPON;
        ?RANK_TYPE_FJARVIS -> ?FJARVIS;
        ?RANK_TYPE_FGUN -> ?FGUN;
        ?RANK_TYPE_FCLOUD -> ?FCLOUD;
        ?RANK_TYPE_FARMOUR -> ?FARMOUR
    end.

get_rank_type_by_foster_cell(CellType) ->
    case CellType of
        ?FHORSE -> [?RANK_TYPE_FHORSE, ?RANK_TYPE_FOSTERS];
        ?FWING  -> [?RANK_TYPE_FWING, ?RANK_TYPE_FOSTERS];
        ?FPEARL -> [?RANK_TYPE_FPEARL, ?RANK_TYPE_FOSTERS];
        ?FWEAPON -> [?RANK_TYPE_FWEAPON, ?RANK_TYPE_FOSTERS];
        ?FJARVIS -> [?RANK_TYPE_FJARVIS, ?RANK_TYPE_AIGIRLS];
        ?FGUN -> [?RANK_TYPE_FGUN, ?RANK_TYPE_AIGIRLS];
        ?FCLOUD -> [?RANK_TYPE_FCLOUD, ?RANK_TYPE_AIGIRLS];
        ?FARMOUR -> [?RANK_TYPE_FARMOUR, ?RANK_TYPE_AIGIRLS]
    end.

get_sub_foster_cell_power(?RANK_TYPE_FOSTERS, Player) ->
    get_sub_foster_cell_power_1(?RANK_TYPE_14600, Player);
get_sub_foster_cell_power(?RANK_TYPE_AIGIRLS, Player) ->
    get_sub_foster_cell_power_1(?RANK_TYPE_14601, Player).

get_sub_foster_cell_power_1(RankTypeList, Player) ->
    #player_status{role_foster = RoleFoster, role_foster_skin = RoleFosterSkin} = Player,
    #role_foster{fosters = Fosters} = RoleFoster,
    #role_foster_skin{fosters = FosterSkins} = RoleFosterSkin,
    lists:foldl(fun(RankType, {AccPower, Grades}) ->
        Cell = get_foster_cell_by_rank_type(RankType),
        {AccPower1, Grades1} =
        case lists:keyfind(Cell, #cell_foster.type, Fosters) of
            #cell_foster{combat = Combat, grade = CellGrade} ->
                {Combat+AccPower, [{Cell, CellGrade}|Grades]};
            _ -> {AccPower, Grades}
        end,
        case lists:keyfind(Cell, #cell_foster_skin.type, FosterSkins) of
            #cell_foster_skin{combat = Combat1} ->
                {Combat1+AccPower1, Grades1};
            _ -> {AccPower1, Grades1}
        end
    end, {0, []}, RankTypeList).

get_rank_config(RankType) ->
    data_ranking:get_rank_config(RankType).

%% 称号相关
get_title_id(RankType, _) ->
    get_title_id(RankType).

get_title_id(RankType) ->
    case data_ranking:get_rank_config(RankType) of
        #rank_config{title_id = TitleId} -> TitleId;
        _ -> 0
    end.

%% 称号名字
get_title_name(RankType) ->
    case data_ranking:get_rank_config(RankType) of
        #rank_config{title_id = TitleId} ->
            case data_designation:get_by_id(TitleId) of
                #base_designation{name = Name} -> Name;
                _ -> ""
            end;
        _ -> ""
    end.

%% 榜单名字
get_rank_type_name(RankType) ->
    case data_ranking:get_rank_config(RankType) of
        #rank_config{rank_name = Name} -> Name;
        _ -> ""
    end.

%% 角色名字
get_id_name(RoleId) ->
    case lib_role:get_role_show(RoleId) of
        [] -> "";
        #ets_role_show{figure = #figure{name = Name}} -> Name
    end.


db_get_role_first_top_reward(RoleId) ->
    case catch db:get_all(?sql_common_rank_role_first_top_select, [RoleId]) of
        DbData = [_|_] ->
            [{RankType, Target} || [RankType, Target] <- DbData];
        [] ->
            [];
        _A ->
            ?ERR("db init error ~p", [_A]),
            []
    end.


get_role_warsoul_info(Player, Des) ->
    #player_status{id = RoleId, off = Off} = Player,
    case Off#status_off.goods_status of
        undefined   -> GoodsStatus = lib_goods_do:get_goods_status(); %% 在线
        GoodsStatus -> GoodsStatus     %% 离线
    end,
    WarSoulList = warsoul_api:get_all_warsoul_list(GoodsStatus),
    EquipList = pack_warsoul_list(WarSoulList),
    lib_server_send:send_to_sid(Des, pt_221, 22112, [RoleId, EquipList]),
    ok.


pack_warsoul_list(WarSoulList) ->
    EquipList   = lists:foldl(fun(#goods{cell = Cell, goods_id = GoodsId, extra_data = ExtraData}, Acc) ->
        case lists:keyfind(?GOODS_OTHER_KEY_WARSOUL_LV, 1, ExtraData) of
            {_, Lv} -> ok;
            _       -> Lv = 0
        end,
        [{GoodsId, Cell, Lv}|Acc]
    end, [], WarSoulList),
    EquipList.