%%%--------------------------------------
%%% module  : pp_player
%%% @author  : xyao
%%% email   : jiexiaowen@gmail.com
%%% Created : 2010.06.13
%%% description:  角色功能管理
%%%--------------------------------------
-module(pp_player).
-export([handle/3]).
-include("common.hrl").
-include("server.hrl").
-include("scene.hrl").
-include("predefine.hrl").
-include("title.hrl").
-include("def_event.hrl").
-include("figure.hrl").
-include("guild.hrl").
-include("dungeon.hrl").
-include("errcode.hrl").
-include("attr.hrl").
-include("team.hrl").
-include("skill.hrl").
-include ("def_goods.hrl").
-include ("arena.hrl").
-include ("profile_photo.hrl").
-include("quickbar.hrl").

%% 查询当前玩家信息(仅能登录时请求一遍)
handle(13001, Status, _) ->
    #player_status{
        id = Id,
        platform = Platform,
        server_id = ServerId,
        server_num = ServerNum,
        server_name = ServerName,
        figure = Figure,
        battle_attr = BattleAttr,
        scene = Scene, x = X, y = Y,
        exp=Exp, exp_lim=ExpLim,
        gold=Gold, bgold=BGold, fgold=FGold, coin=Coin, gfame = GFame,
        combat_power = CombatPower,
        guild = #status_guild{id = GuildId, name = GuildName},
        dungeon = #status_dungeon{dun_id = DunId},
        team = #status_team{team_id=TeamId},
        sid = Sid,
        mate_role_id = MateRoleId,
        last_task_id = LastTaskId,
        reg_time = RegTime, honour = Honour
    } = Status,
    % 暂不需要做Socket发送开关，未来如有需要再在game_conn中补充
    % Sid ! {is_send, true},
    %% 再发送人物信息
    PkCd = lib_player:get_pk_cd_time(Status),
    WearMate = mate_api:get_wear_mate_role(Status),
    {GodId, Hp, HpLim} = god_api:pack_role_user(Status),
    #battle_attr{pk = #pk{pk_value=PkValue}} = BattleAttr,
    {ok, BinRole} = pt_130:write(13001, [Id, Platform, ServerId, ServerNum, ServerName, Figure, BattleAttr, Scene, X, Y, DunId, Exp, ExpLim,
            Gold, BGold, FGold, Coin, Honour, GFame, CombatPower, GuildId, GuildName, PkCd, PkValue, TeamId, MateRoleId, RegTime, WearMate, GodId, Hp, HpLim]),
    BaseAttrList = maps:to_list(BattleAttr#battle_attr.base_attr_map),
    {ok, BaseAttrBin} = pt_130:write(13032, [BaseAttrList]),
    {ok, BinTask} = pt_300:write(30012, [LastTaskId]),
    AllBin = <<BinRole/binary, BaseAttrBin/binary, BinTask/binary>>,
    lib_server_send:send_to_sid(Sid, AllBin),
    %% 1.需要调用change_scene以分配线路 2.前端需要通过12005来驱动12002的加载流程
    pp_scene:handle(12005, Status, [DunId, Scene, 0, ?TRANS_TYPE_SERVER, X, Y]);

%% 查询玩家信息
handle(13004, Status, [Id]) ->
    #player_status{sid = MySid, server_id = MyServerId, id = RoleId} = Status,
    ServerId = mod_player_create:get_real_serid_by_id(Id),
    ModulesPower = lib_player:get_module_power(Status),
    if
        RoleId =:= Id ->
            ok;
        MyServerId =:= ServerId ->
            lib_player:apply_cast(Id, ?APPLY_CAST_STATUS, ?HAND_OFFLINE, lib_player, send_role_info_local, [MySid, ModulesPower]);
        true ->
            clusters_node:apply_cast(clusters_center, apply_cast,
                [ServerId, lib_player, apply_cast,
                    [Id, ?APPLY_CAST_STATUS, ?HAND_OFFLINE, lib_player, send_role_info_kf, [MySid, ModulesPower]]]
            )
    end;

%% 请求玩家铜币和元宝信息
handle(13006, Status, _) ->
    {ok, BinData} = pt_130:write(13006,
        [
            Status#player_status.coin,
            Status#player_status.gold,
            Status#player_status.bgold,
            Status#player_status.fgold,
            Status#player_status.gfame,
            Status#player_status.honour
        ]
    ),
    lib_server_send:send_to_sid(Status#player_status.sid, BinData);

%% 请求快捷栏
handle(13007, Status, _) ->
    #player_status{sid = Sid, quickbar = Quickbar} = Status,
    quickbar_api:notice_quickbar(Sid, Quickbar),
    ok;

%% 保存快捷栏
handle(13008, Status, [Local, Type, _Scheme, Id, _AutoTag] = Setting) ->
    #player_status{skill = Skill, quickbar = QuickBar, sid = Sid, id = RoleId} = Status,
    IsCorrect = lists:member(Local, ?BASE_BTN_LOCS),
    {IsVaild, Code} = case {Type, Local}  of
        {?BTN_SKILL, _Local}  when IsCorrect == true ->
            case lists:keyfind(Id, 1, Skill#status_skill.skill_list) of
                {Id, Lv} when Lv > 0 ->
                    case data_skill:get(Id, Lv) of
                        #skill{is_normal = 0} ->
                            {true, 1};
                        _ ->
                            {false, 0}
                    end;
                _ ->
                    {false, 0}
            end;
        {_Type, _Local} -> {true, 0}
    end,
    {ok, BinData} = pt_130:write(13008, [Code]),
    lib_server_send:send_to_sid(Sid, BinData),
    case IsVaild of
        true ->
            NewQuickbar = quickbar_api:save_quickbar(Setting, QuickBar),
            Status1 = Status#player_status{quickbar = NewQuickbar},
            quickbar_api:db_save_quickbar(RoleId, NewQuickbar),
            mod_scene_agent:update(Status1, [{quickbar_skills, NewQuickbar}]),
            {ok, Status1};
        false -> skip
    end;

%% 玩家当前正在参与的玩法
handle(13009, Status, _) ->
    #player_status{sid = Sid, action_lock = ActionLock} = Status,
    case is_number(ActionLock) of
        true  ->
            {ok, BinData} = pt_130:write(13009, [ActionLock]);
        false ->
            {ok, BinData} = pt_130:write(13009, [0])
    end,
    lib_server_send:send_to_sid(Sid, BinData),
    ok;

%% 替换快捷栏
handle(13010, Status, [Local1, Local2, Scheme]) ->
    #player_status{sid = Sid} = Status,
    {ErrCode, NewStatus} =
    case quickbar_api:role_replace_quickbar(Status, Local1, Local2, Scheme) of
        {false, Reason} ->
            {Reason, Status};
        {ok, Status2} ->
            {?SUCCESS, Status2}
    end,
    {ok, BinData} = pt_130:write(13010, [ErrCode]),
    lib_server_send:send_to_sid(Sid, BinData),
    {ok, NewStatus};

%% 玩家是否可以打开世界等级
handle(13011, Status, _) ->
    #player_status{sid = Sid, figure = Figure} = Status,
    #figure{lv = Lv} = Figure,
    WorldLv = util:get_world_lv(),
    ServerLvExpAdd = data_exp_add:get_add(WorldLv, Lv),
    {ok, BinData} = pt_130:write(13011, [ServerLvExpAdd, WorldLv]),
    lib_server_send:send_to_sid(Sid, BinData),
    {ok, Status};

%% 切换PK状态
handle(13012, Status, [Type]) when Type >= ?PK_PEACE andalso Type =< ?PK_DIFF_SERVER ->
    lib_player:change_pkstatus(Status, Type);

%%请求玩家头像
handle(13017,Status,[ModId,RoleId])->
    if
        RoleId =:= Status#player_status.id ->
            lib_player:send_picture_to_uid(Status, ModId, RoleId);
        true ->
            ServerId = mod_id_create:get_serid_by_id(RoleId),
            case lists:member(ServerId, config:get_merge_server_ids()) of
                true ->
                    lib_player:apply_cast(RoleId, ?APPLY_CAST_STATUS, ?HAND_OFFLINE, lib_player, send_picture_to_uid, [ModId, Status#player_status.id]);
                _ ->
                    Node = clusters_node:get_node(),
                    clusters_node:apply_cast(lib_player, get_picture_from_other_server, [ServerId, RoleId, ModId, Node, Status#player_status.id])
            end
    end;

%% 请求玩家figure
handle(13013, Status, [ServerId, RoleId, ModId]) ->
    if
        RoleId =:= Status#player_status.id ->
            lib_player:send_figure_to_uid(Status, ServerId, ModId, RoleId);
        true ->
            case lists:member(ServerId, config:get_merge_server_ids()) of
                true ->
                    lib_player:apply_cast(RoleId, ?APPLY_CAST_STATUS, ?HAND_OFFLINE, lib_player, send_figure_to_uid, [ServerId, ModId, Status#player_status.id]);
                _ ->
                    Node = clusters_node:get_node(),
                    clusters_node:apply_cast(lib_player, get_figure_from_other_server, [ServerId, RoleId, ModId, Node, Status#player_status.id])
            end
    end;

%% 请求公会会长figure
handle(13014, Status, [ServerId, GuildId, ModId]) ->
    ArgsMap = #{ser_id => ServerId, mod_id => ModId},
    case lists:member(ServerId, config:get_merge_server_ids()) of
        true ->
            mod_guild:send_chief_figure_info(none, Status#player_status.id, GuildId, ArgsMap);
        _ ->
            Node = clusters_node:get_node(),
            clusters_node:apply_cast(lib_guild_api, send_chief_figure_info_in_center, [Node, Status#player_status.id, GuildId, ArgsMap])
    end;

%% 请求跳跃闪现能量同步
handle(13016, Player, _) ->
    NewPlayer = motion_energy:notice_energy(Player),
    {ok, NewPlayer};

%% 玩家红名值
handle(13034, Status, _) ->
    lib_player:send_attribute_change_notify(Status, ?NOTIFY_PK);

%% 玩家消除红名值
handle(13035, Ps, [Num]) when Num > 0 ->
    #player_status{
        id = RoleId, sid = Sid, battle_attr = BA,scene = SceneId, scene_pool_id = ScenePId
        ,copy_id = CopyId, x = X, y = Y
    } = Ps,
    #battle_attr{pk = Pk} = BA,
    #pk{pk_value = PkValue, pk_value_ref = PkValueRef} = Pk,
    if
        PkValue =< 0 -> lib_server_send:send_to_sid(Sid,  pt_130, 13035, [?ERRCODE(err150_pk_value_0), 0, 0]);
        true ->
            GoodsTypeId = ?GOODS_ID_EVIL_REDUCE,
            EffectValue = max(data_goods:get_effect_val(GoodsTypeId, del_pk_value), 1),
            DelNum = Num * EffectValue,
            {UseNum, NewPkValue} = if
              PkValue >= DelNum ->
                  {Num, PkValue - DelNum};
              true -> %% 不需要消耗Num个物品
                  {util:ceil(PkValue / EffectValue), 0}
            end,
            CostList = [{?TYPE_GOODS, GoodsTypeId, UseNum}],
            case lib_goods_api:cost_objects_with_auto_buy(Ps, CostList, red_name_cost, "") of
                {false, ErrorCode, _PS} ->
                    lib_server_send:send_to_sid(Sid, pt_130, 13035, [ErrorCode, 0, 0]);
                {true, NewPs, _NewCostList} ->
                    NewPk = if
                        NewPkValue == 0 ->
                            util:cancel_timer(PkValueRef),
                            {ok, BinData1} = pt_200:write(20015, [RoleId, NewPkValue]),
                            lib_server_send:send_to_area_scene(SceneId, ScenePId, CopyId, X, Y, BinData1),
                            Pk#pk{pk_value = 0, pk_value_change_time = 0, pk_value_ref = undefined};
                        true ->
                            Pk#pk{pk_value = NewPkValue}
                    end,
                    NewPS = NewPs#player_status{battle_attr = BA#battle_attr{pk = NewPk}},
                    lib_player:send_attribute_change_notify(NewPS, ?NOTIFY_PK),
                    mod_scene_agent:update(NewPS, [{battle_attr, NewPS#player_status.battle_attr}]),
                    lib_server_send:send_to_sid(
                        Sid, pt_130, 13035, [?SUCCESS, PkValue - NewPkValue, NewPkValue]
                    )
            end
    end;

%% 请求充值
handle(13051, Status, _) ->
    {ok, NewStatus} = lib_recharge:pay(Status),
    {true, NewStatus};

handle(13080, Status, _) ->
    {ok, BinData} = pt_130:write(13080, [Status#player_status.accname]),
    lib_server_send:send_to_sid(Status#player_status.sid, BinData);

%% 校验是否能上传图片
handle(13082, Status, _) ->
    Res = case Status#player_status.picture_lim == 0 of
        true  -> 1;    %%  1 允许提交头像
        false -> 2     %%  2 你已被管理员禁止设置头像
    end,
    {ok, BinData} = pt_130:write(13082, [Res]),
    lib_server_send:send_to_sid(Status#player_status.sid, BinData);

%% 提交图片
handle(13083, Status, _) ->
    NewPicture = integer_to_list(Status#player_status.id),
    #player_status{id = _RoleId, figure = Figure, picture_lim = PictureLim, sid = Sid} = Status,
    case PictureLim == 0 of
        true ->
            %% 版本号,客户端根据版本号来判断是否请求头像
            NewPictureVer = Figure#figure.picture_ver + 1,
            %% 触发头像更改(在线不在线都需要处理：秘籍才需要这样处理)
            %% lib_player:notify_picture_change(RoleId, NewPicture, NewPictureVer),
            %% 更新玩家身上picture
            {ok, NewStatus1} = lib_player:update_player_picture_online(Status, NewPicture, NewPictureVer),
            Res = 1,
            {ok, BinData} = pt_130:write(13083, [Res, NewPictureVer, NewPicture]),
            lib_server_send:send_to_sid(Sid, BinData),
            {ok, NewStatus1};
        false ->
            Res = 2,    % 后台管理员禁止玩家上传头像
            {ok, BinData} = pt_130:write(13083, [Res, 0, ""]),
            lib_server_send:send_to_sid(Sid, BinData)
    end;

%% 设置GPS经纬度
handle(13084, Status, [Longitude, Latitude]) when is_integer(Longitude) andalso is_integer(Latitude) ->
    {ok, BinData} = pt_130:write(13084, [1]),
    lib_server_send:send_to_sid(Status#player_status.sid, BinData),
    {ok, Status#player_status{longitude=Longitude, latitude=Latitude}};

%% 玩家怒气
handle(13086, #player_status{sid = Sid, battle_attr = BattleAttr}, _) ->
    #battle_attr{anger = Anger, anger_lim = AngerLim} = BattleAttr,
    {ok, BinData} = pt_130:write(13086, [Anger, AngerLim]),
    lib_server_send:send_to_sid(Sid, BinData);

%% 查询角色登录时间
handle(13087, Status, []) ->
    #player_status{
        id = RoleId,
        login_time_before_last = TimeBeforeLast,
        last_login_time = LastLoginTime,
        last_logout_time = LastLogoutTime
    } = Status,
    NowTime = utime:unixtime(),
    {ok, Bin} = pt_130:write(13087, [NowTime, TimeBeforeLast, LastLoginTime, LastLogoutTime]),
    lib_server_send:send_to_uid(RoleId, Bin);

%% 查询角色头像信息
handle(13088, Status, _) ->
    #player_status{profile_photo_info = PhotoInfo, sid = Sid, figure = Figure} = Status,
    #profile_photo_info{photo_list = PhotoList} = PhotoInfo,
    %% 加上转职的头像返回给前端
    #figure{career = Career, profile_photo_id = ProfilePhotoId} = Figure,
    TransformId = transform:get_transform_id(Status),
    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)),
    %% 目前没有上传头像,如果profile_photo_id为0则穿上转职头像(这里暂时只处理创角)
    case ProfilePhotoId of
        0 when TransformId == 0 ->
            case data_transform:get_career_transform_image(Career, TransformId) of
                PhotoId when is_integer(PhotoId) ->
                    {ok, Status1} = handle(13090, Status, [PhotoId]);
                _ ->
                    Status1 = Status
            end;
        _ ->
            Status1 = Status
    end,
    {ok, BinData} = pt_130:write(13088, [AllPhotoList]),
    lib_server_send:send_to_sid(Sid, BinData),
    {ok, Status1};

%% 激活头像
handle(13089, Status, [PhotoId]) ->
    #player_status{sid = Sid} = Status,
    {NewStatus, ErrCode} = case lib_player:activate_profile_photo(Status, PhotoId) of
        {false, ErrorCode} ->
            ReturnErrorCode = ?ERRCODE(err130_is_activated),
            if ErrorCode == ReturnErrorCode ->
                    lib_player:photo_goods_return(Status, PhotoId, ErrorCode);
                true ->
                    {Status, ErrorCode}
            end;
        {ok, Status2} ->
            {Status2, ?ERRCODE(success)}
    end,
    {ok, BinData} = pt_130:write(13089, [ErrCode, PhotoId]),
    lib_server_send:send_to_sid(Sid, BinData),
    {ok, NewStatus};

%% 更换头像
handle(13090, Status, [PhotoId]) ->
    #player_status{sid = Sid} = Status,
    {NewStatus, ErrCode} = case lib_player:change_profile_photo(Status, PhotoId) of
        {false, ErrorCode} ->
            {Status, ErrorCode};
        {ok, Status2} ->
            {Status2, ?ERRCODE(success)}
    end,
    {ok, BinData} = pt_130:write(13090, [ErrCode, PhotoId]),
    lib_server_send:send_to_sid(Sid, BinData),
    {ok, NewStatus};

handle(_Cmd, _Status, _Data) ->
    {error, "pp_player no match"}.
