%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     战魂系统
%%% @end
%%%-------------------------------------------------------------------
-module(warsoul_api).
-author("liushl").

-include("server.hrl").
-include("def_goods.hrl").
-include("warsoul.hrl").
-include("predefine.hrl").
-include("rec_offline.hrl").
-include("goods.hrl").
-include("def_module.hrl").
-include("skill.hrl").
-include("figure.hrl").

%% API
-export([
    calc_power/3,                   %% 计算战魂系统战力
    get_attr/1,                     %% 获得战魂系统总属性
    get_warsoul_power/1,            %% 获得战魂系统总战力
    get_warsoul_skill/1,            %% 获得战魂系统的战斗技能
    include_warsoul_attr/1          %% 统计战魂系统属性
    ,handle_event/2                 %% 事件回调

    ,gm_equipment_all/1
]).

-export([
    get_all_warsoul/0,              %% 获得所有战魂
    get_all_warsoul/1,
    get_all_warsoul_list/0,
    get_all_warsoul_list/1,

    get_warsoul_strength_lv/1,      %% 获得战魂的强化等级
    get_warsoul_type/1,             %% 获得战魂类型
    get_warsoul_star/1,             %% 获取战魂星级
    get_warsoul_kind/1,             %% 获得战魂的属性
    get_warsoul_kind_info/0,        %% 获得战魂信息
    get_warsoul_kind_info/1,

    update_warsoul_array/1,         %% 更新当前阵型
    update_warsoul_power/1          %% 更新战力
]).

-include("rec_event.hrl").
-include("def_event.hrl").
-include("rush_rank.hrl").

%% 处理玩家升级事件
handle_event(PS, #event_callback{type_id = ?EVENT_LV_UP_BF_COUNT_ATTR}) ->
    NewPS = include_warsoul_attr(PS),
    {ok, NewPS};
handle_event(PS, _Event) ->
    {ok, PS}.

%% 计算战魂系统战力 lib_player_attr:update_module_power 回调
calc_power(Player, AttrPower, BaseAttr) ->
    RoleWarSoul = Player#player_status.role_war_soul,
    case RoleWarSoul of
        #role_war_soul{extra_power = ExtraPower, attr = Attr, total_power = OldPower} ->
            PartialAttr = attr_conv:to_attr_record(Attr),
            Power       = lib_player_attr:calc_attr_power_partial(AttrPower, BaseAttr, PartialAttr) + ExtraPower,
            NewPlayer   = Player#player_status{role_war_soul = RoleWarSoul#role_war_soul{total_power = Power}},
            Power =/= OldPower andalso begin
                pp_warsoul:handle(14300, NewPlayer, []),
                lib_common_rank_api:refresh_rank_by_warsoul(NewPlayer),
                lib_rush_rank_api:refresh_rank_by_foster(?RANK_TYPE_RUSH_WARSOUL, NewPlayer),
                custom_act_circle_foster:combat_change_event(NewPlayer, ?RANK_TYPE_RUSH_WARSOUL)
            end,
            {NewPlayer, ExtraPower};
        _ ->
            {Player, 0}
    end.

%% 获得战魂系统总属性
get_attr(Player) ->
    case Player#player_status.role_war_soul of
        #role_war_soul{attr = Attr} ->
            Attr;
        _ ->
            []
    end.

%% 获得战魂系统总战力
get_warsoul_power(Player) ->
    case Player#player_status.role_war_soul of
        #role_war_soul{total_power = Power} ->
            Power;
        _ ->
            0
    end.

%% 获得战魂系统的战斗技能
get_warsoul_skill(Player) ->
    case Player#player_status.role_war_soul of
        #role_war_soul{passive_skills = Skills} ->
            Skills;
        _ ->
            []
    end.
%%---------------------------------------------------------------------
%% @doc 获得战魂
%%---------------------------------------------------------------------
%% 获得所有战魂 dict 格式返回
get_all_warsoul() ->
    GoodsStatus = lib_goods_do:get_goods_status(),
    get_all_warsoul(GoodsStatus).
get_all_warsoul(GoodsStatus) ->
    lib_goods_util:get_location_goods(GoodsStatus#goods_status.dict, ?GOODS_LOC_WAR_SOUL_EQUIP).

%% 获得所有战魂 list 格式返回
get_all_warsoul_list() ->
    GoodsStatus = lib_goods_do:get_goods_status(),
    get_all_warsoul_list(GoodsStatus).
get_all_warsoul_list(GoodsStatus) ->
    lib_goods_util:get_goods_list(GoodsStatus#goods_status.dict, ?GOODS_LOC_WAR_SOUL_EQUIP).

%% 获得战魂的强化等级
get_warsoul_strength_lv(GoodsInfo) ->
    goods_extra_data:extra_data_get(GoodsInfo, ?GOODS_OTHER_KEY_WARSOUL_LV, 0).

%% 获得战魂类型
get_warsoul_type(GoodsInfo) ->
    case data_warsoul:get_war_soul_info(GoodsInfo#goods.goods_id) of
        #base_war_soul_info{type = Type} -> Type;
        _ -> 0
    end.

%% 获得战魂的属性
get_warsoul_kind(GoodsInfo) ->
    case data_warsoul:get_war_soul_info(GoodsInfo#goods.goods_id) of
        #base_war_soul_info{kind = Kind} -> Kind;
        _ -> 0
    end.

%% 获得战魂星级
get_warsoul_star(GoodsInfo) ->
    case data_warsoul:get_war_soul_info(GoodsInfo#goods.goods_id) of
        #base_war_soul_info{star = Star} -> Star;
        _ -> 0
    end.

%% 获得战魂信息：
%% return: [{类型, 数量}],按数量排序
get_warsoul_kind_info() ->
    GoodsStatus = lib_goods_do:get_goods_status(),
    get_warsoul_kind_info(GoodsStatus).
get_warsoul_kind_info(GoodsStatus) ->
    AllWarSoul = get_all_warsoul(GoodsStatus),
    KindInfo =
    dict:fold(
        fun(_Key, GoodsInfo, Temp) ->
            case data_warsoul:get_war_soul_info(GoodsInfo#goods.goods_id) of
                #base_war_soul_info{kind = Kind} ->
                    case lists:keyfind(Kind, 1, Temp) of
                        {Kind, Num} ->
                            lists:keyreplace(Kind, 1, Temp, {Kind, Num + 1});
                        _ ->
                            [{Kind, 1}|Temp]
                    end;
                _ ->
                    Temp
            end
        end, [], AllWarSoul
    ),
    lists:keysort(2, KindInfo).

%%---------------------------------------------------------------------
%% @doc 更新当前阵型-一般上阵和下阵的时候更新
update_warsoul_array(Player) ->
    #player_status{role_war_soul = RoleWarSoul} = Player,
    KindInfo    = get_warsoul_kind_info(),
    %% 找到属性最多的数量
    case KindInfo =/= [] of
        true ->
            {_, Num} = lists:last(KindInfo),
            ArrayId     = update_warsoul_array(data_warsoul:get_all_array(), Num);
        false ->
            ArrayId = 0
    end,
    NewRoleWarSoul = RoleWarSoul#role_war_soul{array_id = ArrayId},
    Player#player_status{role_war_soul = NewRoleWarSoul}.

update_warsoul_array([Id|T], Num) ->
    case data_warsoul:get_war_soul_array(Id) of
        #base_war_soul_array{condition = Num} ->
            Id;
        _ ->
            update_warsoul_array(T, Num)
    end;
update_warsoul_array([], _) -> 0.

%%---------------------------------------------------------------------
%% @doc 更新战力，装备战力计算在回调 lib_player_attr:update_module_power/3 里通过调用?MODULE:calc_power/3计算
update_warsoul_power(Player) ->
    Player1 = include_warsoul_attr(Player),
    Player2 = lib_player:count_player_attribute(Player1),
    lib_player:send_attribute_change_notify(Player2, ?NOTIFY_ATTR),
    mod_scene_agent:update(Player2, [{battle_attr, Player2#player_status.battle_attr}]),
    Player2.

%%---------------------------------------------------------------------
%% @doc 统计战魂系统属性
%% 每件战魂的 基础属性 强化属性 技能
%% 阵型加成
include_warsoul_attr(Player) ->
    #player_status{role_war_soul = RoleWarSoul, off = StatusOff, figure = #figure{lv = RoleLv}} = Player,
    #role_war_soul{array_id = ArrayId} = RoleWarSoul,
    case StatusOff#status_off.goods_status of
        undefined ->
            GoodsStatus = lib_goods_do:get_goods_status(),
            AllWarSoul = get_all_warsoul(GoodsStatus);
        GoodsStatus ->
            AllWarSoul = get_all_warsoul(GoodsStatus)
    end,
    F = fun(_Key, GoodsInfo, {AttrTemp, SkillTemp}) ->
            case data_warsoul:get_war_soul_info(GoodsInfo#goods.goods_id) of
                #base_war_soul_info{attr = BaseAttr = [_|_], skill = Skill= [_|_]} ->
                    %% 基础属性 BaseAttr
                    %% 强化属性
                    StrengthAttr =
                    case data_warsoul:get_war_soul_strength(GoodsInfo#goods.color, get_warsoul_strength_lv(GoodsInfo)) of
                        #base_war_soul_strength{attr = _StrengthAttr = [_|_]} -> _StrengthAttr;
                        _ -> []
                    end,
                    {BaseAttr ++ StrengthAttr ++ AttrTemp, Skill ++ SkillTemp};
                _ ->
                    {AttrTemp, SkillTemp}
            end
        end,
    {GoodsAttr, GoodsSkill}
        = dict:fold(F, {[], []}, AllWarSoul),
    ArrayAttr =
    case data_warsoul:get_war_soul_array(ArrayId) of
        #base_war_soul_array{attr = _ArrayAttr} -> _ArrayAttr;
        _ -> []
    end,
    %% 技能属性
    SkillAttr = lib_skill_attr:count_skill_attr_with_mod_id(?MOD_WARSOUL, GoodsSkill, RoleLv),
    %% 技能虚战力
    ExtraPower = lib_skill:count_skill_power(GoodsSkill),
    %% 过滤出战斗效果的被动技能
    PassiveKills = lib_skill_api:divide_passive_skill(GoodsSkill),
    %% 综合属性
    SumAttr = util:combine_list(SkillAttr ++ ArrayAttr ++ GoodsAttr),
    %% 处理局部系统加成属性
    FinalAttr = lib_player_attr:partial_attr_convert(SumAttr),
    NewRoleWarSoul = RoleWarSoul#role_war_soul{attr = FinalAttr, extra_power = ExtraPower, passive_skills = PassiveKills},
    Player#player_status{role_war_soul = NewRoleWarSoul}.

gm_equipment_all(Player) ->
    #player_status{
        id = RoleId,
        cell_num = CellNum,
        storage_num = StorageNum
    } = Player,
    %% 删除旧装备
    [
        db:execute("delete from goods where id=~p and role_id=~p", [OldId, RoleId])
        || #goods{id = OldId} <- get_all_warsoul_list()
    ],
    AllGoods = data_goods_type:get_by_type(?GOODS_TYPE_WAR_SOUL, ?GOODS_WARSOUL_EQUIPMENT),
    lists:foldl(
        fun(GoodsId, [Cell|T]) ->
            case data_warsoul:get_war_soul_info(GoodsId) of
                #base_war_soul_info{star = 9, color = Color} ->
                    GoodsTypeInfo = data_goods_type:get(GoodsId),
                    GoodsInfo = lib_goods_util:get_new_goods(RoleId, GoodsTypeInfo, []),
                    %% 满级属性
                    ExtraData = [
                        %% 强化等级
                        {?GOODS_OTHER_KEY_WARSOUL_LV, get_max_strength_lv(Color, 0)}
                    ],
                    lib_goods_util:add_goods(
                        GoodsInfo#goods{
                            cell = Cell,
                            num = 1,
                            bind = 1,
                            location = ?GOODS_LOC_WAR_SOUL_EQUIP,
                            extra_data = ExtraData
                        }
                    ),
                    T;
                _ ->
                    [Cell|T]
            end;
            (_, _) ->
                []
        end, [1, 2, 3, 4, 5, 6, 7], AllGoods
    ),
    %% 物品初始化
    GoodsStatus = lib_goods_do:login(RoleId, 0, CellNum, StorageNum),
    lib_goods_do:init_data(GoodsStatus),
    pp_goods:handle(15010, Player, [?GOODS_LOC_WAR_SOUL_EQUIP]),
    warsoul_logic:collect_goods(Player, [{Id, 1} || Id <- AllGoods]),
    Player1 = warsoul_logic:login(Player),
    Player2 = update_warsoul_power(Player1),
    pp_warsoul:handle(14305, Player2, []),
    Player2.

get_max_strength_lv(Color, Lv) ->
    case data_warsoul:get_war_soul_strength(Color, Lv + 1) of
        [] -> Lv;
        _ -> get_max_strength_lv(Color, Lv+1)
    end.

